Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I visualize audio data?

I would like to have something that looks something like this. Two different colors are not nessesary.

audacity on mac
(source: sourceforge.net)

I already have the audio data (one sample/millisecond) from a stereo wav in two int arrays, one each for left and right channel. I have made a few attempts but they don't look anywhere near as clear as this, my attempts get to spikey or a compact lump.

Any good suggestions? I'm working in c# but psuedocode is ok.

Assume we have

  • a function DrawLine(color, x1, y1, x2, y2)
  • two int arrays with data right[] and left[] of lenght L
  • data values between 32767 and -32768

If you make any other assumptions just write them down in your answer.

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

This is how it turned out when I applied the solution Han provided. (only one channel)
alt text http://www.imagechicken.com/uploads/1245877759099921200.jpg

like image 281
Nifle Avatar asked Jun 23 '09 22:06

Nifle


People also ask

What represents audio data?

Files that contain nothing but audio data are known as raw files. They usually contain uncompressed monaural pulse code modulation (PCM) data. In order to use such files, it is necessary to know, or be able to figure out, the sampling rate, resolution, signedness, and endianness of the data.

How is audio data stored?

Digital audio in recording applications is stored on audio-specific technologies including CD, Digital Audio Tape (DAT), Digital Compact Cassette (DCC) and MiniDisc. Digital audio may be stored in a standard audio file formats and stored on a Hard disk recorder, Blu-ray or DVD-Audio.

What is Librosa ML?

Librosa is one of several libraries dedicated to analyzing sounds. Many individuals have used this library for machine learning purposes. Here, different methods to visualize sounds can become seen through advanced algorithmic codes.


1 Answers

You'll likely have more than 1 sample for each pixel. For each group of samples mapped to a single pixel, you could draw a (vertical) line segment from the minimum value in the sample group to the maximum value. If you zoom in to 1 sample per pixel or less, this doesn't work anymore, and the 'nice' solution would be to display the sinc interpolated values. Because DrawLine cannot paint a single pixel, there is a small problem when the minimum and maximum are the same. In that case you could copy a single pixel image in the desired position, as in the code below:

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

Note that Value2Pixel scales a sample value to a pixel value (in the y-direction).

like image 171
Han Avatar answered Sep 23 '22 17:09

Han