2009-06-23 9 views
11

Je voudrais avoir quelque chose qui ressemble à ceci. Deux couleurs différentes ne sont pas nessaires.Comment visualiser des données audio?

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

J'ai déjà les données audio (un échantillon/milliseconde) à partir d'un wav stéréo dans deux tableaux int, un pour chaque canal gauche et à droite. J'ai fait quelques tentatives, mais elles ne semblent pas aussi claires que cela, mes tentatives se résument à un spikey ou à une masse compacte.

De bonnes suggestions? Je travaille en C# mais psuedocode est ok.

Supposons que nous avons

  • une DrawLine fonction (couleur, x1, y1, x2, y2)
  • deux tableaux int avec des données droite [] et à gauche [] de longueur L
  • valeurs de données entre 32767 et -32768

Si vous faites d'autres hypothèses, écrivez-les simplement dans votre réponse.

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

Voici comment cela s'est passé lorsque j'ai appliqué the solution Han provided. (un seul canal)
alt text http://www.imagechicken.com/uploads/1245877759099921200.jpg

+0

Audacity est open source, vous pouvez donc regarder le code. Je suppose quelque chose comme le suivant ... func getHeight (v) {return abs (v) * 32767/viewArea.height/2); samplesPerPixelColumn = samples.len/viewArea.width; pour i = 1 à viewArea.width {avgV = Avg (échantillons [i-i + samplesPerPixelColumn]); colHeight = getHeight (avgV); si avgV> = 0 DrawLine (noir, i, viewArea.height/2, i, (viewArea.height/2) + colHauteur) else DrawLine (noir, i, vueArea.height/2, i, (viewArea.height/2) - colHauteur); Vous aurez probablement besoin de faire un peu d'arrondi/plage de manipulation, mais cela devrait être l'essentiel. – steamer25

+0

Pourquoi ne pas mettre cela dans une réponse. – Nifle

+1

Je voulais vous donner quelque chose qui pourrait être immédiatement utile, mais ne pas être downvoted si une partie de celui-ci était éteint. Plus de pensées: Au lieu de lignes verticales, dessinez des diagonales entre le point précédent et le suivant ...En outre, si vous zoomez suffisamment, vous aurez plusieurs pixels par échantillon. – steamer25

Répondre

2

Vous aurez probablement plus de 1 échantillon pour chaque pixel. Pour chaque groupe d'échantillons mappés à un seul pixel, vous pouvez dessiner un segment de ligne (vertical) entre la valeur minimale du groupe d'échantillons et la valeur maximale. Si vous zoomez à 1 échantillon par pixel ou moins, cela ne marche plus, et la solution "sympa" serait d'afficher les valeurs interpolées. DrawLine ne pouvant pas peindre un seul pixel, il y a un petit problème lorsque le minimum et le maximum sont les mêmes. Dans ce cas, on peut copier une seule image de pixel dans la position désirée, comme dans le code ci-dessous:

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; 
} 

Notez que Value2Pixel échelles une valeur d'échantillon à une valeur de pixel (dans la direction y).

0

Vous voudrez peut-être consulter la langue R pour cela. Je n'ai pas beaucoup d'expérience avec cela, mais il est largement utilisé dans des scénarios d'analyse/visualisation statistiques. Je serais surpris s'ils n'avaient pas une fonction de lissage pour se débarrasser des extrêmes comme vous l'avez mentionné.

Et vous ne devriez avoir aucune difficulté à importer vos données dedans. Non seulement vous pouvez lire des fichiers texte à plat, mais il est également conçu pour être facilement extensible avec C, donc il y a probablement aussi une sorte d'interface C#.

+0

Je doute que l'appel d'une application externe pour dessiner mes bitmaps fonctionnerait. Je suis en train de mettre à jour le bitmap plusieurs fois par seconde. – Nifle