0
0

Hi –

I’m a student at MIT working on my senior project and would really appreciate some help in getting a pitch shifting DSP to work on Windows CE.
I’ve tried posting before with little success, but I’m trying again in hopes that maybe someone will be able to help…

I’m using a DSP callback and the Soundtouch library to pitchshift a stream (without changing frequency…the ultimate goal is to change the tempo, but I figured I could change the pitch with Soundtouch then compensate the frequency with the FSOUND_SetFrequency function). When Soundtouch isn’t processing anything (ie. when I set the pitch to 100%), the callback works just fine. However, once I set Soundtouch to pitchshift (which is pretty CPU intensive, that might have something to do with it?) I get a lot of skipping, like fmod will only play tiny bits of samples.

I’ve posted my callback function if it would help, but basically I’m just wondering if it’s possible that this might be a threading issue? Is it possible that soundtouch is taking up all the CPU to process the samples so fmod can’t play any audio? Or perhaps it’s another issue…
Any suggestions would be greatly appreciated, I’ve been stuck on this for a while.

Here’s my callback code:
[code:3v965jp7]
float pitch_BufOut[409600];
float sampleBuffer[2048];
int pitch_BufOutPosWrite = 0;
int pitch_BufOutPosRead = 0;
int ready = 0;

void * DSP_ReverbCallback(void *originalbuffer, void *newbuffer, int length, void *param)
{
int nSamples;
float l, r;

float *srcleft, *srcright;
srcleft   = ((float *)newbuffer);
srcright  = ((float *)newbuffer)+1;

int totalSamples = 0;

    sound.putSamples(srcleft, length);
    do
    {
        nSamples = sound.receiveSamples(sampleBuffer, 1024);

        totalSamples += nSamples;
        for (int i = 0; i < nSamples*2; i+=2)
        {
            pitch_BufOut[pitch_BufOutPosWrite++] = sampleBuffer[i];
            pitch_BufOut[pitch_BufOutPosWrite++] = sampleBuffer[i+1];
            if (pitch_BufOutPosWrite >= 409600)
                pitch_BufOutPosWrite = 0;
        }
    } while (nSamples != 0);


//*** MAIN LOOP ***
for (int count=0; count<length*2; count+=2)
{
    l = srcleft[count];
    r = srcright[count];
           if (pitch_BufOutPosWrite != pitch_BufOutPosRead)
            {
                l = pitch_BufOut[pitch_BufOutPosRead++];
                r = pitch_BufOut[pitch_BufOutPosRead++];
                if (pitch_BufOutPosRead == 409600)
                    pitch_BufOutPosRead = 0;
                } else {
                l = 0.0f;
                r = 0.0f;
            }

    srcleft[count] = l;
    srcright[count]= r;
}

return newbuffer;

}
[/code:3v965jp7]

Thanks so much!
-Pamela

  • You must to post comments
0
0

Can I use FMOD Ex for Windows CE? I thought it wasn’t supported…If so, I’ll definitely give that a try.

  • You must to post comments
0
0
So if I have a really slow DSP routine like the one above, is there any way to make this work in FMOD? I’ve tried another pitch shifting routine too http://www.dspdimension.com/data/index.html and it does the same thing…I’m guess it’s because the routines are taking too long, but I’m not really sure if there’s anything I can do about that. Some settings I can change, perhaps?
😕
  • You must to post comments
0
0

Ok, that sounds reasonable…
The soundtouch library seems to take either shorts or floats, and FMOD is giving me signed ints, I think (using the default mixer on CE)? So should I clip the ints to shorts, or set soundtouch to use floats (but only give it int data). If that makes any sense…

Thanks so much for your help, Brett!

  • You must to post comments
0
0

Ok i changed my code to use ints instead of floats and it sounds a little better. I can hear the pitch shifting now, but now it sounds like a broken record…the same half-seconf or so of audio just keeps repeating. What are common causes of repeating? Here’s my modified code…

[code:3iw2poi5]
static void _int2Short(SAMPLETYPE *pDest, const int *pSrc, uint uNum)
{
uint i;
for (i = 0; i < uNum; i ++)
{
int temp;

    // saturate result between -32768..32767
    temp = pSrc[i];
    if (temp &gt; 32767)
    {
        temp = 32767;
    } 
    else if (temp &lt; -32768)
    {
        temp = -32768;
    }
    pDest[i] = (signed short)temp;
}

}

int pitch_BufOut[81920];
short sampleBuffer[2048];
int pitch_BufOutPosWrite = 0;
int pitch_BufOutPosRead = 0;

void * DSP_ReverbCallback(void *originalbuffer, void *newbuffer, int length, void *param)
{
int nSamples, l, r;

signed int *srcleft, *srcright;
srcleft   = ((signed int *)newbuffer);
srcright  = ((signed int *)newbuffer)+1;

signed short *soundtouchbuffer;
soundtouchbuffer = new short[length*2];

// *** convert to 16-bit short samples for soundtouch ***
_int2Short(soundtouchbuffer, srcleft, length*2);
sound.putSamples(soundtouchbuffer, length);
   do
{
    nSamples = sound.receiveSamples(sampleBuffer, 1024);
    for (int i = 0; i &lt; nSamples*2; i+=2)
    {
        pitch_BufOut[pitch_BufOutPosWrite++] = sampleBuffer[i];
        pitch_BufOut[pitch_BufOutPosWrite++] = sampleBuffer[i+1];
        if (pitch_BufOutPosWrite &gt;= 81920)
            pitch_BufOutPosWrite = 0;
    }
}

//*** MAIN LOOP ***
for (int count=0; count&lt;length*2; count+=2)
{
    if (pitch_BufOutPosWrite != pitch_BufOutPosRead)
    {
        l = pitch_BufOut[pitch_BufOutPosRead++];
       r = pitch_BufOut[pitch_BufOutPosRead++];
        if (pitch_BufOutPosRead &gt;= 81920)
           pitch_BufOutPosRead = 0;
        } else {
            l = 0;
                r = 0;
        }

    srcleft[count] = l;
    srcright[count]= r;
}

return newbuffer;

}

[/code:3iw2poi5]

Again, it works fine when Soundtouch isn’t doing anything, so it’s probably my internal buffering somewhere…I just don’t know all that much about audio so am not sure quite where to look.

Thanks

  • You must to post comments
0
0

Brett, thanks for all your help.
I forgot to mention that Soundtouch does have a fixed-point setting (to use fixed point integers rather than floats) so I set it to use that. Now, by playing with the buffer sizes and adding some thread sleeps, I can get it to where the pitch is shifted for ~4 or 5 seconds, then it will repeat. If i set my buffer sizes very high (FSOUND_Stream_SetBufferSize(8000) and FSOUND_SetBufferSize(1000) ) the problem is lessened. I also am calling ::Sleep(20) in every DSP callback to give FMOD a chance to fill the sound buffer.
Soundtouch has about a 100ms delay, so my internal buffering needs to take that into account.
Do you think that Soundtouch is too slow, even with the fixed-point setting?

Sorry for all the questions…

  • You must to post comments
0
0

For anyone who’s interested, I was able to get this to work by lowering the mixrate from 22050 (the recommended value for Smartphone) to 11025. Sound quality is still good. Other config values:

FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT);
FSOUND_SetBufferSize(200);
FSOUND_Stream_SetBufferSize(2000);

I used SoundTouch in integer mode, with the QUICKSEEK setting, which significantly reduces the algorithm time.

SoundTouch.setSetting(SETTING_USE_QUICKSEEK, 1);

  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.