0
0

I am trying to use FMOD to playback a sound already loaded into memory.
My problem is the sound comes out distorted, sorta like a chipmunk sound.
I believe the problem is somehow related to how I am setting up the FMOD_CREATESOUNDEXINFO structure.

Here is my code:
[code:18j9xzv7]FMOD_CREATESOUNDEXINFO ex;

    memset(&ex, 0x00, sizeof(FMOD_CREATESOUNDEXINFO));
    ex.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
    ex.length = nthis->datasize;

    ex.numchannels = 1;
    ex.decodebuffersize = ex.defaultfrequency = 32000;
    ex.format = FMOD_SOUND_FORMAT_PCM8;

    FMOD_System_CreateSound(mpSystem,
        0,              //filename
        FMOD_OPENUSER,  //audio type
        &ex,            //SoundExInfo
        &mpSound);      //sound

    if (mpSound)
    {
        void *pDest1 = 0, *pDest2 = 0;
        unsigned int len1 = 0, len2 = 0;

        FMOD_Sound_Lock(mpSound,
            0,
            nthis->datasize,
            &pDest1,
            &pDest2,
            &len1,
            &len2);

        memcpy(pDest1, nthis->data, nthis->datasize);

        FMOD_Sound_Unlock(mpSound,
            pDest1,
            pDest2,
            len1,
            len2);

        FMOD_System_PlaySound(mpSystem,
            FMOD_CHANNEL_FREE,
            mpSound,
            0,
            &pCh);[/code:18j9xzv7]

The sound is a basic WAV file, here is its standard format when saved as a WAV with its standard values:
[code:18j9xzv7]https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

4 bytes – ‘RIFF’ header
4 bytes – chunk size (13C921h)
4 bytes – ‘WAVE’ format

4 bytes – ‘fmt ‘ sub-header
4 bytes – sub-chunk size (10h)
2 bytes – audio format (1h)
2 bytes – number of channels (1h)
4 bytes – sample rate (2256h)
4 bytes – byte rate (2256h)
2 bytes – block align (1h)
2 bytes – bit per sample (8h)
4 bytes – ‘data’ sub-header
4 bytes – data size[/code:18j9xzv7]

I am sure I have the data loaded into memory correctly.
As I change frequency a bit, the sound speeds up and slows down, but I’m not exactly sure what the correct frequency is then.
I tried playing the sound directly from a file with the above WAV header and it played correctly, so I know I am doing something wrong.

For the sound data I give it in memcpy, I don’t give it the WAV header too do I?

Can anyone help me?
Thanks in advance.

  • You must to post comments
0
0

You could just use System::createSound with the FMOD_OPEN_MEMORY flag instead, and pass your data in as the first argument.

[code:338uakbd]
FMOD_System_CreateSound(mpSystem,
nthis->data, //filename or data
FMOD_OPENMEMORY, //mode
&ex, //SoundExInfo
&mpSound); //sound [/code:338uakbd]

[quote:338uakbd]For the sound data I give it in memcpy, I don’t give it the WAV header too do I? [/quote:338uakbd]
You can pass it a wave header but you don’t have to. If all the required information is supplied using the FMOD_CREATESOUNDEXINFO, then you can use FMOD_SOUND_TYPE_RAW and pass in headerless raw data.

  • You must to post comments
0
0

I used ‘FMOD_Sound_GetDefaults’ to get the frequency of the WAV file, and it says 22050.0, which is the sample rate in the header, but I accidently wrote it down incorrectly (2256h instead of 5622h lol).

Thanks for your help Peter.

I first tried what you said, using FMOD_OPENMEMORY and passing it the data with a WAV header first, and didn’t change anything in my SOUNDEXINFO and the sound played fine.
This is good, but I don’t want to rely on constantly recreating the sound’s data memory just to include a WAV header in front of it.

I tried removing the header, still using FMOD_OPENMEMORY, and put in the suggested sound type as FMOD_SOUND_TYPE_RAW, but now the CreateSound returns FMOD_ERR_FORMAT. Even FMOD_SOUND_TYPE_WAV doesn’t work either.

EDIT:
I added the flag FMOD_OPENRAW and the CreateSound finally passed but the sound is back to being distorted the same as before. So I’m still stuck at the same place as I was before.

Is there some other setting a need in the SOUNDEXINFO that I am missing?
My current code:

[code:fccoyg0p] data = nthis->data; //headerless data
newsize = nthis->datasize;

    memset(&ex, 0x00, sizeof(FMOD_CREATESOUNDEXINFO));
    ex.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
    ex.length = newsize;

    ex.numchannels = 1;
    ex.decodebuffersize = ex.defaultfrequency = 22050;
    ex.format = FMOD_SOUND_FORMAT_PCM8;
    ex.suggestedsoundtype = FMOD_SOUND_TYPE_RAW;

    res = FMOD_System_CreateSound(mpSystem,
        data,   //filename or data
        FMOD_OPENMEMORY | FMOD_OPENRAW, //extra settings
        &ex,            //SoundExInfo
        &mpSound);      //sound

    if (mpSound)
    {
        FMOD_System_PlaySound(mpSystem,
            FMOD_CHANNEL_FREE,
            mpSound,
            0,
            &pCh);[/code:fccoyg0p]
  • You must to post comments
0
0

I figured the out the problem after googling various things for an hour.

The data has to be converted from from unsigned char to signed char.
[code:1yyzhf37]for (int a = 0; a < newsize; a++)
{
data[a] -= (char)128;
}[/code:1yyzhf37]

With that, the sound finally plays correctly.

I guess there isn’t a way for fmod to do the conversion for me? (Besides doing it during a pcmreadcallback)

  • You must to post comments
0
0

I’m glad you resolved your issue, it never occured to me that it might be a signed/unsigned mismatch. FMOD can do the coversion inside the WAV codec but I don’t think there is any interface to get that conversion when using RAW.

  • You must to post comments
0
0

Ok.
Thank you for your help.

  • You must to post comments
Showing 5 results
Your Answer

Please first to submit.