0
0

Hi there,

I’m making a tracker in C++ (Builder) using fmod and one of the things I would like to be in it, is a kind-of sample editor…so I’m trying to draw a waveform of the sampledata and provide in the basic cut-copy-paste actions, like you’ll find in any wave editor.
Currently I have the following: After loading a sample into a TMemoryStream object I create a stream and a sample with a pointer to the TMemoryStream’s memory. After that I get the length of the data in samples and the length of the data in bytes and by doing bytes/samples I get the size of a single “chunk”. Then I execute FSOUND_Sample_Lock & -Unlock 1024 times in equal intervals to get the actual data, wich I put in a structure with 1024 int-pointers for 2 BytesPerSample-data and 1024 long-pointers for 4BytesPerSample.
But the values I get don’t make any sense…the first part (sometimes 10 bytes, sometimes 1000) consists out of 19928??? – values and all of the rest is 0. What I would like to know:

Is it correct that I cast the ptr1 value to a long/int (depending on the bytes per sample) and get the amplitude from that?
And how do I get the actual ampitude of those values? I’m fairly new to audio programming and I don’t really understand what the wave-data really presents. I mean…wave data consists out of more things then just the amplitude, right? So when I create an array of data-blocks, what should I do with this data to get the actual amplitude so I can draw a waveform…
I recon it must be something quite simple, but I don’t get it yet…if someone could help me out with this, I would really appreciate it…

Thanx in advance,

Dhalsim
Dhalsim@mail.com

  • You must to post comments
0
0

Digital audio in its purest form is nothing but a long stream of amplitudes–purest form meaning uncompressed. Most amplitude data is integer-based (newer formats permit floating-point data) and may be any number of bits but usually is 8 or 16-bit per channel. Most multi-channel audio is interleaved, so stereo audio consists of one amplitude value for the left immediately followed by the value for the right. Note that there are two amplitude values, but it is considered only one [i:13a2aux6]sample[/i:13a2aux6]. So one sample of quadrophonic 8-bit audio is actually 32-bits in length (4 channels * 8 bits/channel).

Sound is, of course, just changes in air pressure. This pressure may be positive (compression) or negative (rarefraction). 16-bit audio data uses a [i:13a2aux6]signed[/i:13a2aux6] 2-byte integer, which allows values from -32768 to 32767. However in 8-bit audio data, the data uses an [i:13a2aux6]unsigned[/i:13a2aux6] single-byte integer, which uses values from 0 to 255. This means that an amplitude of zero, while stored as the value 0 in 16-bit audio, is actually stored as 128 in 8-bit audio. So just be careful how you interpret the binary data. (FMOD makes the comment that all sample data should be considered [i:13a2aux6]signed[/i:13a2aux6], so you may have to experiment.)

The lock/unlock methods should be returning pointers to the audio data, not the actual data itself. You must dereference the pointers to obtain the audio data. Storing these pointers usually will not work, since they are usually invalid after unlocking.

Here is a function that, albeit inefficient, gets the amplitude at a specific sample.
[code:13a2aux6]// Our audio is single channel 16-bit.
typedef signed short AUDIO;

AUDIO GetAmplitudeAtOffset(FSOUND_SAMPLE *sptr, int offset)
{
// The value we will be returning.
AUDIO amplitude = 0;

// Calculate the offset in bytes, since FSOUND_Sample_Lock uses bytes.
int offsetBytes = offset * sizeof(AUDIO);

// The lock information.
void *ptr1 = NULL, *ptr2 = NULL;
unsigned int len1 = 0, len2 = 0;

// Do the lock.
if (FSOUND_Sample_Lock(sptr, offsetBytes, sizeof(AUDIO), &ptr1, &ptr2, &len1, &len2))
{
    // Dereference the pointer to get the data.
    amplitude = *((AUDIO *)ptr1);

    // Unlock.
    FSOUND_Sample_Unlock(sptr, ptr1, ptr2, len1, len2);
}

// Finished.
return amplitude;

}[/code:13a2aux6]

  • You must to post comments
0
0

Mmmm…now it always returns 0…I don’t get any errors/exceptions, but neither any values…what am I doing wrong?

  • You must to post comments
0
0

Ooops…sorry, I made a really stupid mistake. It is working now! Thanx a lot for helping me out here…this is great!

-Greetings
Dhalsim

  • You must to post comments
Showing 3 results
Your Answer

Please first to submit.