Capítulo 4: Resultados experimentales
4.5 Pruebas de funcionamiento
4.5.2 Grabación en un periodo largo
Otra de las pruebas necesarias es realizar una grabación larga, que tendrá una duración de una hora, que es el tiempo aproximado que graba un CD, a diferencia de que no tendrá comparación el tamaño final de la grabación con la capacidad de almacenamiento que tiene un CD, debido a que esta aplicación es limitada a voz con calidad telefónica de 4 KHz.
Para realizar la grabación se puede ayudar de alguna persona que hable durante una hora o bien auxiliarse de alguna grabación de algún aparato reproductor. Para este caso se usa un documental de internet, se pone a reproducir y se comienza la captura a través del micrófono frente a las bocinas de la computadora sin necesidad de que hable directamente una persona.
Finalmente el resultado es observado en la figura 4.17, en donde aparece la Interfaz Gráfica de Usuario con la grabación de una hora finalizada. También puede apreciarse el espectro resultante de la grabación.
Figura 4. 17 Resultado de la grabación de 1 hora continua
Otra prueba consistió en comprobar que tan eficiente es el tiempo de grabación capturado con el reloj programado en la IGU en comparación de un reloj externo. El tiempo de grabación para ambos relojes fue considerando para una grabación de una hora. La siguiente imagen muestra el resultado de la prueba de funcionamiento para el tiempo de captura de una hora de audio. Como podemos apreciar, la IGU ha terminado de capturar el tiempo de grabación mientras el reloj digital del celular marca que ha transcurrido 0:57:07.39 (el tamaño del archivo resultante fue de 27.4 MB).
Capítulo 4: Resultados experimentales 115
Figura 4. 18 Diferencia de tiempo de un cronometro contra la IGU en una hora.
Ahora vamos a calcular cuánto tiempo de adelanto existe por parte de la IGU para posteriormente obtener una relación del más adelanto para otros tiempos de grabación más superiores. Los cálculos se muestran a continuación. En primera instancia sabemos que:
( 30)
( 31)
Si sustituimos la ecuación (30) en la ecuación (31) obtenemos:
( 32) Con el resultado anterior podemos saber los ms contenidos en una hora de grabación:
( 33) Ahora basándonos en los cálculos anteriores obtenemos el tiempo de grabación obtenida con el reloj digital que resulto de 0:57:07.39 (57 minutos, 7 segundos y 390 milésimas).
( ) ( ) ( 34) Con las ecuaciones (33) y (34) podemos obtener el tiempo de adelanto de la IGU generada en una hora:
Capítulo 4: Resultados experimentales 116
El resultado anterior muestra la cantidad en ms del tiempo de adelanto de una grabación con duración de una hora. Si pasamos el resultado anterior a minutos para hacerlo más entendible resulta:
( 36) Tomando en cuenta el resultado anterior, se muestra a continuación una relación de la desviación del adelanto del reloj de la IGU con forme a periodos más largos de tiempo:
Tabla 4. 2 Diferencia de tiempo de un cronometro contra la IGU. Horas Adelanto en ms hh:mm:ss:ms
1 172,610 00:02:52.610
2 345,220 00:05.45.220
4 690,440 00:11:30.440
8 1,380,880 00:23:00.880
Figura 4. 19 Diferencia de tiempo de un cronometro contra la IGU.
Con lo que podemos concluir que el reloj interno de la IGU no es del todo preciso, ya que existe un adelanto de 2:52.61 por cada hora transcurrido por un reloj digital. Calcular el adelanto para un tiempo superior a 18 horas no sería práctico ya que como lo mencionamos en el desarrollo, la máxima capacidad de grabación para la IGU en un formato de archivo WAV es de 9 horas.
1, 172610 2, 345220 4, 690440 8, 1380880 0 200000 400000 600000 800000 1000000 1200000 1400000 1600000 0 2 4 6 8 10
Diferencia de tiempo de un
cronometro contra la IGU
Adelanto en ms
Horas Milisegundos
Capítulo 4: Resultados experimentales 117
4.5.3 Prueba a diferentes locutores
La última prueba es la grabación de un mismo texto leído por distintos locutores; de esta manera, al hacer un análisis escuchando a cada uno de ellos leyendo el mismo texto, se puede deducir la efectividad en cuanto a claridad del mensaje, que es uno de los objetivos principales, obtener un mensaje entendible de voz. Para la prueba, se pidió a los locutores leyeran el decálogo del politécnico frente al micrófono para poder capturar la grabación y así al finalizar se les hizo escucharla pidiendo su opinión en cuanto a la claridad del mensaje; es decir, que tan entendible era, tras haber sido grabada en este formato de baja calidad. Los resultados fueron capturados en la siguiente tabla.
Tabla 4. 3 Estadística de entendimiento del mensaje con grabaciones a diferentes locutores Claridad
Locutor Muy mala Mala Regular Buena
Muy buena Ho mbres Nicolás – 26 años X Daniel – 24 años X Alberto – 28 años X
Juan Pablo – 23 años X
Alejandro -23 años X Gonzalo – 49 años X Mario – 51 años X Yael – 9 años X Gerardo – 23 años X Diego – 24 años X M u je re s Esther – 46 años X Dámaris – 22 años X Miriam – 17 años X Elizabeth – 27 años X Jessica – 23 años X Zeyra – 22 años X Verónica – 16 años X Alejandra – 21 años X Nancy – 21 años X Sara – 17 años X
Es evidente que cada locutor tiene un timbre de voz distinto, por lo que cada grabación entre locutores se escucha diferente, además de que su voz grabada no se escucha igual a su voz original, por la finalidad de obtener una calidad telefónica; sin embargo, es lo más parecida y
Capítulo 4: Resultados experimentales 118
comparando a todos los locutores con el mismo mensaje, cada uno determinó la inteligibilidad del mensaje como se muestra en la tabla 4.2 y en la gráfica siguiente.
Figura 4. 20 Gráfica estadística de inteligibilidad del mensaje en una grabación
Con los resultados obtenidos en la encuesta, en una escala de muy mala, mala, regular, buena y muy buena, se obtiene que un 0% calificó muy mala, un 5% mala, un 30% regular, el 50% como buena y el 15% restante con la máxima calificación, muy buena. Así, se concluye que la inteligibilidad del mensaje es aceptable para la mayoría de las personas y es útil para grabar voz calidad telefónica, con la finalidad de tener un mensaje entendible con poca cantidad de almacenamiento y fácil transmisión.
0 2 4 6 8 10
Muy mala Mala Regular Buena Muy buena
0 1 6 10 3 Pers o n as
Inteligibilidad del mensaje
CONCLUSIONES 119
CONCLUSIONES
El objetivo general y los objetivos particulares fueron alcanzados ya que se obtuvo el archivo de audio en formato WAV que fue sometido a algunas pruebas como portabilidad, duración y una prueba a distintos locutores interpretando el mismo mensaje.
La grabadora digital de voz realizada en este proyecto tiene algunas limitantes que pueden ser mejoradas a futuro. La calidad de grabación es baja, debido a que solo se requiere tener un mensaje entendible de la voz. Para fines prácticos, usar la menor calidad posible, sin llegar a la distorsión del mensaje, reducirá el ancho de banda y podrá ser transmitido por casi cualquier canal, además de los beneficios en cuanto a espacio de almacenamiento son muy altos comparados con una grabación de audio que contempla de los 20 Hz a los 20,000 HZ.
Una de las principales mejoras sería aumentar la calidad de la grabación considerando un ancho de banda mayor, de modo que no sea únicamente para voz, sino para audio en general o por lo menos un ancho de banda mayor a 4KHz. Aumentar el ancho de banda mejorará considerablemente la calidad, sin embargo se requerirá de un muestreo mucho mayor que deberá ser adaptado al hardware o bien buscar alguno más rápido. Otra opción que mejorará mucho la calidad es aumentar el ancho de palabra; para este caso se usó de 8 bits, sin embargo usar otro hardware que permita un muestreo de 16 bits aumentará la calidad considerablemente.
En cuanto a la adquisición de datos, tuvo que ser adaptada a un envío por paquetes de 8 muestras, debido a que se tenía un tiempo de muestreo de 125 us y la Interfaz Gráfica de Usuario (IGU) realizada en Visual Studio 2010 presentó complicaciones con la adquisición a esta velocidad. Para resolver estos problemas de sincronización el sistema de adquisición de datos se adaptó a la forma ya mencionada, envió por paquetes; de esta manera, 8 muestras de 125 us suman un tiempo de 1 ms, tiempo necesario para que la IGU no pierda datos. También para evitar retrasos en la adquisición, se evitaron procesos innecesarios en la misma, como la graficación en tiempo real. Simplemente se capturan los datos obtenidos y son mandados a un arreglo tipo string, donde una vez capturados los datos, son tratados para acondicionar de acuerdo a los estándares establecidos en WAV. Más opciones de codificación para el archivo de audio final también son mejoras considerables para el proyecto, ya que le da al usuario una mayor gama de opciones de acuerdo a sus necesidades.
La interfaz de comunicación es otro punto crítico del proyecto que puede mejorarse; para este caso se hizo uso del puerto serial con el que fue necesario un adaptador serial-USB, porque a la actualidad ya no es común encontrar en los equipos este tipo de conexión. Usar directamente una interfaz USB aumentará la velocidad de transmisión del canal, y así transmitir señales con mayor ancho de banda, además de que no será necesario un adaptador como en el caso de este proyecto.
CONCLUSIONES 120
La adición del formato de salida MP3 fue gracias a la ayuda del software Lame de licencia LGPL, que puede ser llamado desde la misma interfaz para que al usuario le sea transparente dicha conversión. Finalmente se obtienen ambos archivos, dándole al usuario la opción de conservar los dos y comparar por sí mismo la calidad de ellos; que con pruebas a distintos locutores concluyeron que era aceptable la claridad del mensaje en ambos formatos y no existía mucha diferencia entre ellos.
Apéndices 121
Apéndices 122
Apéndice A
Programación del microcontrolador en lenguaje C
********************************************************************************* * PROGRAMA DE LA ADQUISICION DE DATOS
********************************************************************************* * Escuela: IPN - ESIME Zacatenco
* Autor: Antonio Bautista Gustavo
* Cureño Martínez Humberto Yahveh
********************************************************************************/ #include <p18cxxx.h>
/***************************** Bits de Configuración ***************************/ #pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board) #pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2 #pragma config FOSC = HSPLL_HS
#pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = OFF #pragma config BOR = ON #pragma config BORV = 3
#pragma config VREGEN = ON
#pragma config WDT = OFF #pragma config WDTPS = 32768 #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config PBADEN = OFF #pragma config CCP2MX = ON #pragma config STVREN = ON #pragma config LVP = OFF #pragma config ICPRT = OFF #pragma config XINST = OFF #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CP2 = OFF #pragma config CP3 = OFF #pragma config CPB = OFF #pragma config CPD = OFF #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRT2 = OFF #pragma config WRT3 = OFF #pragma config WRTB = ON #pragma config WRTC = OFF #pragma config WRTD = OFF #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTR2 = OFF #pragma config EBTR3 = OFF #pragma config EBTRB = OFF
/****** Este programa prueba el hardware de la tarjeta con el bootloader *******/ #define L1 LATAbits.LATA4 #define L2 LATAbits.LATA5 #define L3 LATCbits.LATC0 #define L4 LATCbits.LATC1 /****************************** Entradas Digitales *****************************/ #define sw2 PORTBbits.RB5 #define sw3 PORTBbits.RB4
Apéndices 123
Las variables utilizadas en el programa son las siguientes:
int resultado: Ésta variable es de tipo entero de 16 bits y en ésta se almacenan los resultados de la conversión las lecturas obtenidas del convertidor analógico digital.
int i: esta variable es de tipo entero y funciona como un acumulador de la lectura de los caracteres. El valor se inicializa en 0 y el máximo es 7.
char y[ ]: Éste arreglo es de tipo carácter y en él se almacenan cada uno de los caracteres que se van a enviar. El valor mínimo que pude tener es 0 y el valor máximo es 255. /****************************** V A R I A B L E S ******************************/ #pragma udata int resultado; int i = 0; char y[];
/********************** DEFINICION DE ALGUNAS CONSTANTES ***********************/ #define TIMER0L_VAL 0x12
#define TIMER0H_VAL 0xFD
/************************ DECLARACION DE LOS PROTOTIPOS ************************/ void YourHighPriorityISRCode(void); void YourLowPriorityISRCode(void); void configUSART(void); void config(void); void CfgADC(void); void configTemp0(void);
void TXbyte(unsigned char data);
/****************************** VECTOR REMAPPING *******************************/
#define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
/*******************************************************************************/ extern void _startup (void); // See c018i.c in your C18 compiler dir #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void) {
_asm goto _startup _endasm }
/*******************************************************************************/ #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void) {
_asm goto YourHighPriorityISRCode _endasm }
/*******************************************************************************/
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS void Remapped_Low_ISR (void)
{
_asm goto YourLowPriorityISRCode _endasm }
#pragma code
//************************** VECTOR DE ALTA PRIORIDAD **************************/ #pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode() {
Apéndices 124
//AGREGAR CODIGO
} //This return will be a "retfie fast", since this is in a #pragma interrupt section /******************** VECTOR DE INTERRUPCION BAJA PRORIDAD *********************/
#pragma interruptlow YourLowPriorityISRCode void YourLowPriorityISRCode()
{
//AGREGAR CODIGO }
El programa principal se conforma de las siguientes funciones e instrucciones:
configTemp0(): Ésta instrucción manda a llamar la función que se encarga de la configuración de los tiempos de cada uno de los datos que van a ser enviados.
CfgADC(): Ésta instrucción manda a llamar la función, que se encarga de todas las configuración del convertidor analógico digital.
configUSART(): Ésta instrucción manda a llamar la función USART, la cual tiene la función de configurar el modulo universal de comunicación serie asíncrona entre el transmisor (TX) y receptor (RX).
El while(1) es un ciclo infinito que estará ahí mientras
L3 = 1: Es el Led 3 de la tarjeta que sirve como un simple indicador de que el programa está funcionando.
resultado = getADC(): En la variable resultado se almacenan los resultados de la conversión analógico digital. El ADC tiene un ancho de palabra de 10 bits por lo que el valor máximo de resultados que vamos a tener en la variable resultado es de 1024 ( ).
y[i] = resultado*0.25: Él arreglo y[i]almacenan cada uno de los caracteres que se van a enviar. Como sólo se requiere una resolución para un ancho de palabra de 8 bits, multiplicamos el valor leído en resultado por 0.25 para tener 256 valores diferentes ( ).
if(i==7): El programa va a entrar a esta condición cuando se hayan completado las ocho muestras (recordar que i es el acumulador del nú mero de caracteres leídos), una vez estando en esta condición llama a la función TXbyte que va a enviar cada uno de los caracteres; seguida de esta cadena se envía el salto de carro TXbyte(0x0D) y el salto de línea TXbyte(0x0A).
/****************************** PROGRAMA PRINCIPAL *****************************/ void main (void)
{
config(); configTemp0(); CfgADC(); configUSART();
T0CON=0B00000111; // Deshabilitado el timer0 y prescaler a 256 INTCON=0B00000000; // Pone a ceros registro INTCON
//while(sw3); //transmitir=1; while(1) { if (RCREG == '1') { L3=1; resultado=getADC(); y[i]= resultado*0.25; if(i==7) { TXbyte(y[0]); TXbyte(y[1]); TXbyte(y[2]); TXbyte(y[3]); TXbyte(y[4]); TXbyte(y[5]); TXbyte(y[6]); TXbyte(y[7]); TXbyte(0x0D); TXbyte(0x0A); i=0; } i++; configTemp0(); } L3=0; }
Apéndices 125
}
/*******************************************************************************/ void configUSART(void)
{ unsigned char temp;
SSPCON1 = 0; // Asegura que el módulo SPI no esté habilitado TRISCbits.TRISC7=1; // Entrada de datos - terminal Rx
TRISCbits.TRISC6=0; // Salida de datos - terminal Tx SPBRG = 25; // Configura 9600 bauds para Fosc de 48 MHz
SPBRGH = 0; // (SPBRG=103 y SPBRGH=0 para 115 kbps) //225
TXSTA = 0x24; // Habilita modo de 16 bits con BRGH=1 //4
RCSTA = 0x90; // Recepción continua en Rx BAUDCON = 0x08; // BRG16 = 1,
temp = RCREG; // Limpia registro del receptor (hacerlo 2 veces) temp = RCREG; //RCREG = buffer del receptor
} /******************************************************************************/ void config(void) { ADCON1 |= 0x0F; TRISB=0xFF;
ADCON1=0x0E; //RA0 se configura como la terminal analógica AN0 TRISA=0X01; //RA0(AN0) es entrada y las demás del puerto son salidas LATA=0X00; //Leds indicadores de nivel apagados
TRISC=0X00; LATC=0X00; }
/*******************************************************************************/ void CfgADC(void)
{ ADCON0=0x00; //La señal de entrada del ADC se lee en AN0
ADCON2=0X8C; //Configura el reloj del ADC y el tiempo de adquisición ADCON0bits.ADON=1; //Enciende el ADC
}
/*******************************************************************************/ int getADC(void)
{ int resultado;
ADCON0bits.GO = 1; //Inicio de conversión
while(ADCON0bits.NOT_DONE); //Espera se termine la conversión resultado=(int)(ADRESH*256) + ADRESL;
return resultado; }
/*******************************************************************************/ void TXbyte(unsigned char data)
{
while(TXSTAbits.TRMT==0);
TXREG = data; //TXREG = buffer del transmisor
} /*******************************************************************************/ void configTemp0(void) { T0CON = 0b10001000; TMR0H = TIMER0H_VAL; TMR0L = TIMER0L_VAL;
while(INTCONbits.TMR0IF == 0) // Mientras la bandera no se halla desbordado
{} // hace nada, espera que termine la interrupcion
INTCONbits.TMR0IF = 0; // Al desbordarse la bandera sale del while T0CONbits.TMR0ON=0; // Paramos el timer0 para que no empiece hasta }
Apéndices 126
Programación de la Interfaz Gráfica de Usuario en lenguaje C#
La interfaz gráfica de usuario se realizó en C# con ayuda del software Visual Studio 2010 Ultimate. En éste programa se reciben los datos del microcontrolador y se estructuran para un archivo con formato de audio WAV.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.IO; using System.Diagnostics; namespace IGU {
publicpartial class Form1 : Form
{
#region Inicializacion de variables string[] POT = new string[67108864];
byte[] mBuffer = new byte[268435456]; // 536870912--- CHUNK DE DATOS--- 536,870,912 Bytes = 512 MB 4294967296
byte[] array = new byte[8];
byte[] data = new byte[268435456]; // CHUNK DE DATOS EN MODO LITTLE ENDIAN byte[] SubChunk2_Size = new byte[4];
int x = 44; //Número de la muestra, inicializado en 44 por las cabeceras que anteceden de WAV
int j = 0; int i = 0; int parar = 0; int cont = 0;
int x1, y1, x2, y2, resolucion_x;
string sPathName_enc; // Direccion de Lame.exe para la codificacion a MP3 string sFileName_wav; // Dirección del archivo WAV de origen
string sFileName_mp3; // Direccion para el archivo de salida MP3
//bool bandera; // Bandera para encontrar "\" y modificar URL destino int size; // Tamaño de la URL destino
byte[] arrayWAV = new byte[100]; // Arreglo en Bytes de URL WAV byte[] arrayMP3 = new byte[100]; // Arreglo en Bytes de URL MP3 byte[] arrayURL = new byte[100]; // Arreglo en Bytes de URL //string codificador;
bool bWait; // Bandera de codificacion a MP3
#endregion
public Form1() {
InitializeComponent(); serialPort1.Open();
serialPort1.Encoding = Encoding.GetEncoding(28591); }
private void BotonGrabar_Click(object sender, EventArgs e) {
parar = Int32.Parse(textBox1.Text) * 1000; byte[] adquiriendo = new byte[1];
adquiriendo[0] = 0x31; //ASCII "1"
serialPort1.Write(adquiriendo, 0, adquiriendo.Length);
#region Obtencion de datos
///////////////////////// OBTENCION DE DATOS ////////////////////////////////////////// for (cont = 0; cont < parar; cont++)
{ i++; POT[cont] = serialPort1.ReadLine(); serialPort1.DiscardInBuffer(); if (i == 999) { i = 0;
Apéndices 127
j++;
label1.Text = j.ToString(); }
} //Fin de la adquisición de datos //byte[] adquiriendo = new byte[1]; adquiriendo[0] = 0x30; //ASCII "0"
serialPort1.Write(adquiriendo, 0, adquiriendo.Length);
MessageBox.Show("Grabación terminada, presione aceptar y esperé un momento");
#endregion
#region Generación de muestraas
/////////////////////// GENERACIÓN DE MUESTRAS //////////////////////////////////////// for (cont = 0; cont < parar; cont++)
{
int a = POT[cont].Length; if (a == 9)
{
array = System.Text.Encoding.GetEncoding(28591).GetBytes(POT[cont]); for (int dato = 0; dato < 8; dato++)
{
if (array[dato] == 0 || /*array[dato] == 32 || array[dato] == 150 ||*/ array[dato] == 128) {
mBuffer[x + dato] = mBuffer[x + dato - 1]; }
else
{
mBuffer[x + dato] = array[dato]; } } x = x + 8; } else {
for (int dato = 0; dato < a; dato++) {
if (array[dato] == 0 || /*array[dato] == 32 || array[dato] == 150 || */array[dato] == 128) {
mBuffer[x + dato] = mBuffer[x + dato - 1]; }
else
{
mBuffer[x + dato] = array[dato]; }
}
for (int dato = a; dato < 8; dato++) {
mBuffer[x + dato] = mBuffer[x + dato - 1]; }
x = x + 8; }
} //Fin de la obtención de muestras individuales
#endregion
}//Fin del botón Grabar
private void BotonNuevaGrabacion_Click(object sender, EventArgs e) {
Array.Clear(mBuffer, 0, x); //Borra el Chunk de datos Array.Clear(POT, 0, x); //Borra el Chunk de datos x = 44; j = 0; i = 0; parar = 0; cont = 0; pictureBox1.Refresh(); label1.Text = ""; }
private void guardarGrabaciónToolStripMenuItem_Click(object sender, EventArgs e) {
#region Cabeceras del archivo WAV //Identificador RIFF
mBuffer[0] = 0x52; mBuffer[1] = 0x49; mBuffer[2] = 0x46; mBuffer[3] = 0x46;
Apéndices 128
string valor_hex1 = (x - 8).ToString("X8"); SubChunk2_Size = StringToByteArray(valor_hex1); mBuffer[4] = SubChunk2_Size[3]; //0xA4; mBuffer[5] = SubChunk2_Size[2]; //0x3E; mBuffer[6] = SubChunk2_Size[1]; //0x00; mBuffer[7] = SubChunk2_Size[0]; //0x00; //formato WAVE mBuffer[8] = 0x57; mBuffer[9] = 0x41; mBuffer[10] = 0x56; mBuffer[11] = 0x45; //Subchunk "fmt" mBuffer[12] = 0x66; mBuffer[13] = 0x6D; mBuffer[14] = 0x74; mBuffer[15] = 0x20;
//Longitud de formato de audio mBuffer[16] = 0x10; mBuffer[17] = 0x00; mBuffer[18] = 0x00; mBuffer[19] = 0x00; //Formato de audio mBuffer[20] = 0x01; mBuffer[21] = 0x00; //Número de canales mBuffer[22] = 0x01; mBuffer[23] = 0x00; //Frecuencia de muestreo mBuffer[24] = 0x40; mBuffer[25] = 0x1F; mBuffer[26] = 0x00; mBuffer[27] = 0x00; //Tasa de bytes (bytes/seg) mBuffer[28] = 0x40; mBuffer[29] = 0x1F; mBuffer[30] = 0x00; mBuffer[31] = 0x00; //Alineamiento de bloques mBuffer[32] = 0x01; mBuffer[33] = 0x00; //Bits por muestra mBuffer[34] = 0x08; mBuffer[35] = 0x00; //Subchunk "data" mBuffer[36] = 0x64; mBuffer[37] = 0x61; mBuffer[38] = 0x74; mBuffer[39] = 0x61; //Longitud de campo de datos
string valor_hex2 = (x - 44).ToString("X8"); SubChunk2_Size = StringToByteArray(valor_hex2); mBuffer[40] = SubChunk2_Size[3]; //0x80; mBuffer[41] = SubChunk2_Size[2]; //0x3E; mBuffer[42] = SubChunk2_Size[1]; //0x00; mBuffer[43] = SubChunk2_Size[0]; //0x00;
#endregion
#region Guardar con SaveFileDialog
SaveFileDialog file = new SaveFileDialog(); file.Filter = "Archivo de Texto (.wav) |*.wav"; file.DefaultExt = ".wav";
file.Title = "Guardar grabación como..."; DialogResult dialogResult = file.ShowDialog(); if (dialogResult == DialogResult.OK)
{
if (String.IsNullOrEmpty(file.FileName)) {
//Inform the user }
string path = file.FileName; FileInfo fi = new FileInfo(path); // Open the stream for writing. using (FileStream fs = fi.OpenWrite()) {
Apéndices 129
// Add some information to the file. fs.Write(mBuffer, 0, x);
}
//MessageBox.Show(path); //Muestra direccion de archivo WAV sFileName_wav = @path;
}
#endregion
#region (Sin uso) Guardar mBuffer en ruta predefinida /*System.IO.FileStream oFileStream = null;
oFileStream = new System.IO.FileStream("C:\\Users/YAHVEH/Dropbox/TESIS/SOFTWARE/grabador/ciclos/bin/Debug/grabacion.wav", System.IO.FileMode.Create); oFileStream.Write(mBuffer, 0, x); //mBuffer.Length -> x oFileStream.Close(); */ #endregion
#region (Sin uso) Direcciones origen y destino predefinidas para codificacion MP3 /* sPathName_enc = @"C:\Users\YAHVEH\Dropbox\TESIS\SOFTWARE\grabador\ciclos\bin\Debug"; sFileName_wav = @"C:\Users\YAHVEH\Dropbox\TESIS\SOFTWARE\grabador\ciclos\bin\Debug\grabacion.wav"; sFileName_mp3 = @"C:\Users\YAHVEH\Dropbox\TESIS\SOFTWARE\grabador\ciclos\bin\Debug\grabacionMP3.mp3"; */ #endregion size = sFileName_wav.Length;