2009-06-23 14 views
11

Mi piacerebbe avere qualcosa che assomigli a questo. Due colori diversi non sono necessari.Come visualizzare i dati audio?

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

Ho già i dati audio (un campione/millisecondi) da un WAV stereo a due array int, uno ciascuno per il canale destro e sinistro. Ho fatto alcuni tentativi ma non sembrano neanche lontanamente chiari come questo, i miei tentativi arrivano a spikey o un grumo compatto.

Qualche suggerimento? Sto lavorando in C# ma psuedocode è ok.

Supponiamo di avere

  • una funzione DrawLine (colore, x1, y1, x2, y2)
  • due array int con i dati a destra [] e sinistro [] di lunghezza L
  • valori dei dati tra il 32767 e -32768

Se si apportano altre ipotesi basta scrivere giù nella vostra risposta.

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

Ecco come è avvenuto quando ho applicato the solution Han provided. (Un solo canale)
alt text http://www.imagechicken.com/uploads/1245877759099921200.jpg

+0

Audacity è open source quindi è possibile controllare il codice. Assumerei qualcosa di simile al seguente ... func getHeight (v) {return abs (v) * 32767/viewArea.height/2); samplesPerPixelColumn = samples.len/viewArea.width; per i = 1 per viewArea.width {avgV = Avg (campioni [i-i + samplesPerPixelColumn]); colHeight = getHeight (avgV); se avgV> = 0 DrawLine (nero, i, viewArea.height/2, i, (viewArea.height/2) + colHeight) else DrawLine (nero, i, viewArea.height/2, i, (viewArea.height/2) - colHeight); Probabilmente avrai bisogno di fare un po 'di arrotondamento/gestione della gamma, ma quello dovrebbe essere il succo. – steamer25

+0

Perché non lo metti in una risposta. – Nifle

+1

Volevo darti qualcosa che potrebbe essere immediatamente utile ma non avere downvoted se parte di esso fosse disattivato. Altri pensieri: anziché le linee verticali, disegna diagonali tra il precedente punto del grafico e il prossimo ...Inoltre, se lo zoom è sufficiente, avrai più pixel per campione. – steamer25

risposta

2

Probabilmente avrai più di un campione per ogni pixel. Per ciascun gruppo di campioni mappati su un singolo pixel, è possibile disegnare un segmento di linea (verticale) dal valore minimo nel gruppo di campioni al valore massimo. Se si esegue lo zoom in 1 campione per pixel o meno, questo non funziona più e la soluzione "carina" sarebbe quella di visualizzare i valori sinc interpolati. Poiché DrawLine non può dipingere un singolo pixel, c'è un piccolo problema quando il minimo e il massimo sono uguali. In questo caso è possibile copiare una singola immagine di pixel nella posizione desiderata, come nel seguente codice:

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

noti che Value2Pixel scala un valore campione ad un valore di pixel (in direzione y).

0

si potrebbe voler esaminare la lingua R per questo. Non ho molta esperienza con esso, ma è usato in gran parte negli scenari statistici di analisi/visualizzazione. Sarei sorpreso se non avessero una funzione di levigatura per sbarazzarsi degli estremi come hai detto tu.

E non dovresti avere problemi a importare i tuoi dati. Non solo puoi leggere file di testo flat, ma è anche progettato per essere facilmente estendibile con C, quindi probabilmente c'è anche un qualche tipo di interfaccia C#.

+0

Dubito che chiamare un'applicazione esterna per disegnare i miei bitmap funzionerebbe. Sto aggiornando la bitmap molte volte al secondo. – Nifle

Problemi correlati