2009-06-23 14 views
11

Me gustaría tener algo que se parece a esto. Dos colores diferentes no son necesarios.¿Cómo visualizo los datos de audio?

audacity on mac http://audacity.sourceforge.net/about/images/audacity-macosx.png

que ya se disponen de datos de audio (una muestra/milisegundos) de un archivo WAV estéreo en dos matrices INT, uno para cada canal izquierdo y derecho. He hecho algunos intentos pero no se ven tan claros como este, mis intentos llegan a ser puntiagudos o un bulto compacto.

¿Alguna buena sugerencia? Estoy trabajando en C# pero psuedocode está bien.

Asumamos que tenemos

  • un DrawLine función (color, x1, y1, x2, y2)
  • dos matrices int con los datos de la derecha [] y derecha [] de longitud L valores de datos
  • entre 32767 y -32768

Si tiene alguna otra suposición simplemente escríbalas en su respuesta.

for(i = 0; i < L - 1; i++) { 
    // What magic goes here? 
} 

Así es como resultó cuando apliqué the solution Han provided. (solo un canal)
alt text http://www.imagechicken.com/uploads/1245877759099921200.jpg

+0

Audacity es de código abierto para que pueda ver el código. Asumiría algo como lo siguiente ... func getHeight (v) {return abs (v) * 32767/viewArea.height/2); samplesPerPixelColumn = samples.len/viewArea.width; para i = 1 para viewArea.width {avgV = Avg (samples [i-i + samplesPerPixelColumn]); colHeight = getHeight (avgV); if avgV> = 0 DrawLine (negro, i, viewArea.height/2, i, (viewArea.height/2) + colHeight) else DrawLine (negro, i, viewArea.height/2, i, (viewArea.height/2) - colHeight); Probablemente necesites hacer un poco de manejo de redondeo/rango, pero esa debería ser la esencia. – steamer25

+0

¿Por qué no pones eso en una respuesta? – Nifle

+1

Quería darte algo que pudiera ser útil de inmediato pero que no te desanime si parte de él estaba desactivado. Más pensamientos: en lugar de líneas verticales, dibuje diagonales entre el punto del gráfico anterior y el siguiente ...Además, si amplía lo suficiente, tendrá múltiples píxeles por muestra. – steamer25

Respuesta

2

Es probable que tenga más de 1 muestra por cada píxel. Para cada grupo de muestras mapeadas en un solo píxel, puede dibujar un segmento de línea (vertical) desde el valor mínimo en el grupo de muestra hasta el valor máximo. Si amplía a 1 muestra por píxel o menos, esto ya no funciona, y la solución "agradable" sería mostrar los valores interpolados de sinc. Dado que DrawLine no puede pintar un solo píxel, existe un pequeño problema cuando el mínimo y el máximo son los mismos. En ese caso, se podría copiar una imagen de un píxel en la posición deseada, como en el código de abajo:

double samplesPerPixel = (double)L/_width; 
double firstSample = 0; 
int endSample = firstSample + L - 1; 
for (short pixel = 0; pixel < _width; pixel++) 
{ 
    int lastSample = __min(endSample, (int)(firstSample + samplesPerPixel)); 
    double Y = _data[channel][(int)firstSample]; 
    double minY = Y; 
    double maxY = Y; 
    for (int sample = (int)firstSample + 1; sample <= lastSample; sample++) 
    { 
     Y = _data[channel][sample]; 
     minY = __min(Y, minY); 
     maxY = __max(Y, maxY); 
    } 
    x = pixel + _offsetx; 
    y1 = Value2Pixel(minY); 
    y2 = Value2Pixel(maxY); 
    if (y1 == y2) 
    { 
     g->DrawImageUnscaled(bm, x, y1); 
    } 
    else 
    { 
     g->DrawLine(pen, x, y1, x, y2); 
    } 
    firstSample += samplesPerPixel; 
} 

Tenga en cuenta que Value2Pixel escala un valor de muestra a un valor de píxel (en la dirección y).

0

Es posible que desee consultar el lenguaje R para esto. No tengo mucha experiencia con esto, pero se usa principalmente en escenarios de análisis estadístico/visualización. Me sorprendería que no tuvieran una función de suavizado para deshacerse de los extremos como usted mencionó.

Y no debería tener problemas para importar sus datos en él. No solo puede leer archivos de texto plano, sino que también está diseñado para ser fácilmente extensible con C, por lo que probablemente también exista algún tipo de interfaz C#.

+0

Dudo que llamar a una aplicación externa para dibujar mis bitmaps funcione. Estoy actualizando el mapa de bits muchas veces por segundo. – Nifle

Cuestiones relacionadas