2009-06-23 12 views
11

Chciałbym mieć coś, co wygląda tak. Dwa różne kolory nie są konieczne.Jak wizualizować dane audio?

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

mam już dane audio (jedna próbka/milisekund) od wav stereo w dwóch tablicach int, po jednym dla lewego i prawego kanału. Podjąłem kilka prób, ale nie wyglądają tak jasno, jak to, moje próby stają się spiczaste lub zwarte.

Jakieś dobre sugestie? Pracuję w języku C#, ale psuedocode jest w porządku.

Załóżmy, że mamy

  • DrawLine funkcja kolorze (x1, y1, X2, Y2)
  • dwa Int tablice z danymi prawo [] i lewo [] o długości L
  • wartości danych między 32767 a -32768

Jeśli masz inne założenia, po prostu zapisz je w swojej odpowiedzi.

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

Tak się okazało po złożeniu the solution Han provided. (Tylko jeden kanał)
alt text http://www.imagechicken.com/uploads/1245877759099921200.jpg

+0

Audacity jest open source, więc możesz spojrzeć na kod. Zakładam coś takiego jak ... func getHeight (v) {return abs (v) * 32767/viewArea.height/2); samplesPerPixelColumn = samples.len/viewArea.width; dla i = 1 to viewArea.width {avgV = Avg (sample [i-i + samplesPerPixelColumn]); colHeight = getHeight (avgV); jeśli avgV> = 0 DrawLine (czarny, i, viewArea.height/2, i, (viewArea.height/2) + colHeight) else DrawLine (czarny, i, viewArea.height/2, i, (viewArea.height/2) - colHeight); Prawdopodobnie będziesz musiał wykonać pewne operacje zaokrąglania/zasięgu, ale to powinno być najważniejsze. – steamer25

+0

Dlaczego nie umieszczasz tego w odpowiedzi. – Nifle

+1

Chciałem dać ci coś, co może być od razu pomocne, ale nie zostanie obniżone, jeśli część z nich jest wyłączona. Więcej myśli: zamiast pionowych linii, narysuj przekątne między poprzednim punktem wykresu a następnym ...Ponadto, jeśli powiększysz wystarczająco, będziesz mieć wiele pikseli na próbkę. – steamer25

Odpowiedz

2

Prawdopodobnie będziesz mieć więcej niż 1 próbkę dla każdego piksela. Dla każdej grupy próbek zmapowanych do pojedynczego piksela można narysować (pionowy) odcinek linii od wartości minimalnej w grupie próbek do wartości maksymalnej. Jeśli powiększysz do 1 próbki na piksel lub mniej, to już nie działa, a "miłym" rozwiązaniem byłoby wyświetlanie wartości interpolowanych sinc. Ponieważ DrawLine nie może namalować pojedynczego piksela, występuje mały problem, gdy wartości minimalne i maksymalne są takie same. W takim przypadku można skopiować pojedynczy piksel obrazu w żądanym położeniu, jak w poniższym kodzie:

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

Zauważ, że Value2Pixel skaluje wartość próbki do wartości piksela (w kierunku y).

0

Czasami warto spojrzeć na język R do tego. Nie mam z tym dużego doświadczenia, ale jest on wykorzystywany głównie w scenariuszach analizy statystycznej/wizualizacji. Byłbym zaskoczony, gdyby nie mieli funkcji wygładzania, aby pozbyć się skrajności, o których wspomniałeś.

Nie powinieneś mieć problemów z importowaniem do niego danych. Nie tylko można czytać płaskie pliki tekstowe, ale także można je łatwo rozszerzyć za pomocą C, więc prawdopodobnie istnieje również jakiś interfejs C#.

+0

Wątpię, żeby zadziałało wywołanie zewnętrznej aplikacji do narysowania moich bitmap. Aktualizuję mapę bitową wiele razy na sekundę. – Nifle

Powiązane problemy