C++ Pointer PCM Data Access FMOD Sound Lock

BlitzMax Forums/BlitzMax Programming/C++ Pointer PCM Data Access FMOD Sound Lock

tesuji(Posted 2012) [#1]
Hi,

I would like to be able to speedily generate a visual representation of entire waveforms based on raw PCM data using the FMOD audio lib (via BaH.FMOD). Getting a bit stuck on how to access the PCM data after a call out to C. Any help would be appreciated.

The FMOD API docs says that the Sound Lock method is best suited for that purpose but alas, it doesn't appear to be present in the bmax wrapper so I've attempted to add it myself. The sound lock definition appeared to be present in the C header files for the FMOD lib. I seem to be most of the way there to hooking it up but I'm having a problem getting visibility of the PCM data in Blitzmax. This may be exacerbated by my lack of experience with C++ ;-)

Anyhow, here's what I've got so far. The sound lock call appears to work in that it returns the correct length vars but as soon as I try and access the byte ptr from bmax it blows up with a memory access violation. Accessing the pointers from C++ works so I suspect it's something to do with how the pointer is being passed back or used in bmax land (this is on a Mac BTW, although shouldn't be too different on Windows).

sound_lock_test.bmx



Modifications to BaH.FMOD

fmod.bmx - additional method in Type TFMODSound
	Method Lock:Int( offset:Int, length:Int, ptr1:Byte Ptr, ptr2:Byte Ptr, len1:Int Var, len2:Int Var )
		Local result:Int = bmx_FMOD_Sound_Lock(soundPtr, offset, length, ptr1, ptr2, len1, len2)
		Return result 
	End Method


common.bmx - C function declaration in Externs
	Function bmx_FMOD_Sound_Lock:Int(handle:Byte Ptr, offset:Int, length:Int, p1:Byte Ptr, p2:Byte Ptr, l1:Int Var, l2:Int Var)



glue.cpp - additional C wrapper function
extern "C" {
	FMOD_RESULT bmx_FMOD_Sound_Lock(FMOD_SOUND * sound, unsigned int offset, unsigned int length, void *ptr1, void *ptr2, unsigned int *len1, unsigned int *len2);

..

}

FMOD_RESULT bmx_FMOD_Sound_Lock(FMOD_SOUND * sound, unsigned int offset, unsigned int length, void *ptr1, void *ptr2, unsigned int *len1, unsigned int *len2) {
	FMOD_RESULT result =  FMOD_Sound_Lock(sound, offset, length, &ptr1, &ptr2, len1, len2 );	
	return result;
}


The FMOD API docs define sound lock like this :

Sound::lock

Returns a pointer to the beginning of the sample data for a sound.

C++ Syntax

FMOD_RESULT Sound::lock(
unsigned int offset,
unsigned int length,
void ** ptr1,
void ** ptr2,
unsigned int * len1,
unsigned int * len2
);

Parameters

offset
Offset in bytes to the position you want to lock in the sample buffer.

length
Number of bytes you want to lock in the sample buffer.

ptr1
Address of a pointer that will point to the first part of the locked data.

ptr2
Address of a pointer that will point to the second part of the locked data. This will be null if the data locked hasn't wrapped at the end of the buffer.

len1
Length of data in bytes that was locked for ptr1

len2
Length of data in bytes that was locked for ptr2. This will be 0 if the data locked hasn't wrapped at the end of the buffer.


Return Values

If the function succeeds then the return value is FMOD_OK.
If the function fails then the return value will be one of the values defined in the FMOD_RESULT enumeration.

Remarks

You must always unlock the data again after you have finished with it, using Sound::unlock.
With this function you get access to the RAW audio data, for example 8, 16, 24 or 32bit PCM data, mono or stereo data, and on consoles, vag, xadpcm or gcadpcm compressed data. You must take this into consideration when processing the data within the pointer.

Last edited 2012