Ayuda más que urgente

11/01/2006 - 18:30 por Daniel Kurman | Informe spam
Señores. Tengo un problema desde hace varios días y no lo puedo resolver y
ya estoy con los tiempos acotados.

El siguiente codigo debería tomar el buffer proveniente de un wave y
dividirlo en distintos samples, según el sample rate y pasar cada uno a una
matriz x[] de tipo float (o byte). Creo que estoy utilizando mal el
ReadInt16, he intentado con el ReadBytes, pero tampoco.

int Samples = m_RecBuffer.Length / format.nBlockAlign;
BinaryReader From = new BinaryReader(new MemoryStream(m_RecBuffer, 0,
m_RecBuffer.Length));
float[] x = new float[Samples];
for (int i = 0; i < Samples; i++)
{
x[i] = From.ReadInt16() / (float)SAMPLE_RATE;
}


Le pido por favor a quien sepa sobre el tema, me responda lo antes que
pueda, dado que no encuentro la salida y ya no me quedan tiempos.

Muchas gracias por adelantado.

Preguntas similare

Leer las respuestas

#1 A.Poblacion
11/01/2006 - 19:37 | Informe spam
"Daniel Kurman" wrote in message
news:%
[...] Creo que estoy utilizando mal el
ReadInt16, he intentado con el ReadBytes, pero tampoco.



El código tiene buen aspecto. Cuando dices que no funciona, ¿qué
síntomas te da? Si lo que te ocurre es que el array de floats recibe valores
incorrectos, se me ocurre una posible causa: El ReadInt16 espera encontrarse
los valores en formato "little endian" (es decir, primero el byte con los
bits menos significativos). Si el búfer que trae los datos los tiene en
formato "big endian", entonces tendrás que leerlos como bytes y procesarlos
en el orden contrario (el primero*256+el segundo, en lugar de al revés -
¿has probado de las dos formas?)
Respuesta Responder a este mensaje
#2 Daniel Kurman
11/01/2006 - 19:49 | Informe spam
no, lo estaba enviando así. Ni idea de little endian o big endian. El
ingreso del sonido proviene del microfono de la placa de sonido de la PC,
tal vez esto lo aclare. Esto lo estoy utilizando para luego analizar la
presencia de códigos DTMF mediante Goertzel, pero soy nuevo en esta materia.

tampoco entiendo mucho esto de el primero y el segundo. Como hago para leer
del buffer el "primero" para multiplicarlo por 256 y sumarle el segundo.
Perdón la ignorancia, pero me he metido en algo un poco complicado, al menos
para mi.

Gracias

"A.Poblacion" escribió en
el mensaje news:
"Daniel Kurman" wrote in message
news:%
[...] Creo que estoy utilizando mal el
ReadInt16, he intentado con el ReadBytes, pero tampoco.



El código tiene buen aspecto. Cuando dices que no funciona, ¿qué
síntomas te da? Si lo que te ocurre es que el array de floats recibe valores
incorrectos, se me ocurre una posible causa: El ReadInt16 espera encontrarse
los valores en formato "little endian" (es decir, primero el byte con los
bits menos significativos). Si el búfer que trae los datos los tiene en
formato "big endian", entonces tendrás que leerlos como bytes y procesarlos
en el orden contrario (el primero*256+el segundo, en lugar de al revés -
¿has probado de las dos formas?)
Respuesta Responder a este mensaje
#3 Daniel Kurman
11/01/2006 - 20:41 | Informe spam
Luego de responder, encontré en Internet una rutina que sobreescribe el
binaryreader, de manera de chequear antes si es big endian o little endian.
En caso de ser little, lee como viene, si no, convierte antes. La adjunto
por si a alguien le sirve. No lo probé aún completamente, pero al correrlo,
detectó que era Big Endian, por lo tanto, tenías razón, era seguramente eso.

Gracias

Adjunto la clase

public enum EndianMode
{
LittleEndian,
BigEndian
}
public class EndianBinaryReader : BinaryReader
{
public EndianBinaryReader(Stream stream, Encoding encoding) : base(stream,
encoding)
{
}
public EndianBinaryReader(Stream stream) : base(stream)
{
}
private EndianMode _endianMode;
public EndianMode EndianMode
{
get { return _endianMode; }
set { _endianMode = value; }
}
public override short ReadInt16()
{
if (this.EndianMode == EndianMode.BigEndian)
{
return base.ReadInt16();
}
else
{
short byte1 = base.ReadByte();
short byte2 = base.ReadByte();
short result = (short) ((byte1 << 8) + byte2);
return result;
}
}
}


"A.Poblacion" escribió en
el mensaje news:
"Daniel Kurman" wrote in message
news:%
[...] Creo que estoy utilizando mal el
ReadInt16, he intentado con el ReadBytes, pero tampoco.



El código tiene buen aspecto. Cuando dices que no funciona, ¿qué
síntomas te da? Si lo que te ocurre es que el array de floats recibe valores
incorrectos, se me ocurre una posible causa: El ReadInt16 espera encontrarse
los valores en formato "little endian" (es decir, primero el byte con los
bits menos significativos). Si el búfer que trae los datos los tiene en
formato "big endian", entonces tendrás que leerlos como bytes y procesarlos
en el orden contrario (el primero*256+el segundo, en lugar de al revés -
¿has probado de las dos formas?)
Respuesta Responder a este mensaje
#4 A.Poblacion
11/01/2006 - 22:41 | Informe spam
"Daniel Kurman" wrote in message
news:uKwsm$
tampoco entiendo mucho esto de el primero y el segundo. Como hago para
leer
del buffer el "primero" para multiplicarlo por 256 y sumarle el segundo.



Tú mismo lo has contestado en tu segundo mensaje. Es la parte que hace
esto:
short byte1 = base.ReadByte();
short byte2 = base.ReadByte();
short result = (short) ((byte1 << 8) + byte2);

Básicamente lo que hace es leer 8 bits (ReadByte) dos veces, en lugar de
leer de golpe los 16 bits que lee el ReadInt16. A continuación "junta" esos
dos trozos de 8 bits para dar lugar a 16 en el orden correcto.

Lo de (byte1<<8) arroja el mismo resultado que (byte1*256).
Respuesta Responder a este mensaje
#5 Daniel Kurman
12/01/2006 - 02:24 | Informe spam
De todas maneras, muchas gracias. Has sido de mucha ayuda.

un saludo

"A.Poblacion" wrote in
message news:
"Daniel Kurman" wrote in message
news:uKwsm$
> tampoco entiendo mucho esto de el primero y el segundo. Como hago para
> leer
> del buffer el "primero" para multiplicarlo por 256 y sumarle el segundo.

Tú mismo lo has contestado en tu segundo mensaje. Es la parte que hace
esto:
short byte1 = base.ReadByte();
short byte2 = base.ReadByte();
short result = (short) ((byte1 << 8) + byte2);

Básicamente lo que hace es leer 8 bits (ReadByte) dos veces, en lugar


de
leer de golpe los 16 bits que lee el ReadInt16. A continuación "junta"


esos
dos trozos de 8 bits para dar lugar a 16 en el orden correcto.

Lo de (byte1<<8) arroja el mismo resultado que (byte1*256).


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida