0
0

I want to use fmod to control the music
but i face a problem when I want to speed up or down the music

the function I use is setFrequency
like follow….

for( int i = 0 ; i < 6 ; i++ ){
channel[i]->setFrequency( Some_Frequency );
}

it can change the speed of music, but it also CHANGE THE PITCH!!

can i have some way to avoid this problem, or there have another way to change the speed without pitch

                 thaks       m(_ _)m
  • You must to post comments
0
0

You probably want to look at the FMOD_DSP_PITCHSHIFT

  • You must to post comments
0
0

I have solve this problem without setFrequency. I use SoundTouch (opensource library for partial pitch and tempo correction).

I use three features of FMOD:
1. Custom sound with my callbacks on readData and setPosition. This for send sound to output device.
2. Custom DSP. This for collect sound data from Sound.
3. NOSOUND_NRT. This for convert all sounds to single format (PCMFLOAT) to activate my custom DSP.

[code:23t9fxle]

include "soundchannel.h"

include "WaveSound.h"

include "SoundSystem.h"

include <QTimer>

include <math.h>

include "SoundTouch/SoundTouch.h"

include <QMessageBox>

class WaveSound : public QObject
{
Q_OBJECT
public:
WaveSound(const QString &fileName);

long length();

protected:
FMOD::Sound *sound;
friend class SoundSystem;
friend class SoundChannel;
};

WaveSound::WaveSound(const QString &fileName)
{
FMOD_RESULT result;
FMOD_CREATESOUNDEXINFO exinfo;
FMOD_MODE mode = FMOD_2D | FMOD_OPENUSER;

    mode |= FMOD_LOOP_NORMAL;
    mode |= FMOD_SOFTWARE;

    memset(&amp;exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.length           = 0;
    exinfo.numchannels      = 2;
    exinfo.defaultfrequency = 44100;
    exinfo.format           = FMOD_SOUND_FORMAT_PCMFLOAT;

// SoundSystem – is real soundsystem device.
result = SoundSystem::fmodSystem()->createStream(fileName.toLocal8Bit(), FMOD_2D|FMOD_SOFTWARE|FMOD_OPENONLY | FMOD_ACCURATETIME, &exinfo, &sound);
ERRCHECK(result);
}

long WaveSound::length(){
unsigned int len=0;
sound->getLength(&len,FMOD_TIMEUNIT_PCM);
return len;
}

class SoundChannel : public QObject
{
Q_OBJECT
public:
SoundChannel();
void setSound(WaveSound *sound);
bool isPaused() const;
bool isPlaying() const;
long getPosition() const;
public slots:
void play();
void setPaused(bool paused);
void stop();
void setPosition(long pos);

void setTempo(double a);
void setPitch(double a);

private slots:
void updatePosition();
signals:
void positionChanged(long pos);
protected:
static FMOD_RESULT F_CALLBACK SoundChannel::mycallback(FMOD_CHANNEL *fchannel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2);
static FMOD_RESULT F_CALLBACK SoundChannel::pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen);
static FMOD_RESULT F_CALLBACK SoundChannel::pcmsetposcallback(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype);

static FMOD_RESULT F_CALLBACK SoundChannel::DSPGetResultCallback(FMOD_DSP_STATE *pDspState,
     float *pInBuf,float *pOutBuf, unsigned int nSamples,
     int nInChannels, int nOutChannels);

WaveSound *sound;
FMOD::Channel* channel;
QTimer *updateTimer;
bool paused;
long startPosition;
long position;
bool atEnd;

soundtouch::SoundTouch touch;

FMOD::System *locSystem; // NO_SOUND ENGINE
FMOD::Channel* locChannel; // NO_SOUND CHANNEL

};

SoundChannel::SoundChannel()
{
FMOD_RESULT result;

sound=0;
channel=0;

locSystem=0;
locChannel=0;
atEnd=true;

updateTimer=new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),SLOT(updatePosition()));
paused=false;
position=startPosition=0;

// Create NO_SOUND System Engine with a channel
result=FMOD::System_Create(&amp;locSystem);
ERRCHECK(result);
result=locSystem-&gt;setOutput(FMOD_OUTPUTTYPE_NOSOUND_NRT);
ERRCHECK(result);
result=locSystem-&gt;init(2, FMOD_INIT_NORMAL, NULL);
locSystem-&gt;setSoftwareFormat(44100,FMOD_SOUND_FORMAT_PCM16,FMOD_SPEAKERMODE_STEREO,0,FMOD_DSP_RESAMPLER_LINEAR);
ERRCHECK(result);
result=locSystem-&gt;setUserData(this);
ERRCHECK(result);

FMOD_DSP_DESCRIPTION  dspdesc;
FMOD::DSP *dsp;
memset(&amp;dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION));
strcpy(dspdesc.name, &quot;Get Result DSP unit&quot;);
dspdesc.channels = 0;
dspdesc.userdata=this;
qDebug()&lt;&lt;&quot;channel=&quot;&lt;&lt;this;
dspdesc.read = DSPGetResultCallback;
result=locSystem-&gt;createDSP(&amp;dspdesc, &amp;dsp);
ERRCHECK(result);
result=locSystem-&gt;addDSP(dsp,0);
ERRCHECK(result);

}

// DSP to collect sound data and send it to SoundTouch
// SOUND_NRT – is Not Real Time processing, System::update() cause this function
FMOD_RESULT F_CALLBACK SoundChannel::DSPGetResultCallback(FMOD_DSP_STATE *pDspState,
float *pInBuf,
float *pOutBuf,
unsigned int nSamples,
int nInChannels,
int nOutChannels) {
FMOD::DSP *dsp=(FMOD::DSP *)(pDspState->instance);
SoundChannel *channel=0;
dsp->getUserData((void**)&channel);

channel-&gt;touch.putSamples(pInBuf,nSamples);
channel-&gt;position+=nSamples;

return FMOD_OK;

}

void SoundChannel::setSound(WaveSound *sound){
this->sound=sound;
position=0;
emit positionChanged(position);
}

// Get sound data from SoundTouch
// If buffer is empty do NRT::update() to fill buffer.
FMOD_RESULT F_CALLBACK SoundChannel::pcmreadcallback(FMOD_SOUND *fsound, void *data, unsigned int datalen)
{
FMOD::Sound *sound = (FMOD::Sound *)fsound;
SoundChannel *channel=0;
sound->getUserData((void**)&channel);

soundtouch::SoundTouch &amp;touch=channel-&gt;touch;

int bps=1;
int channels=1;
int bits;
{
    FMOD_SOUND_TYPE  type;
    channel-&gt;sound-&gt;sound-&gt;getFormat(&amp;type,0,&amp;channels,&amp;bits);
    bps=bits*channels/8;
}

unsigned int length=0;
channel-&gt;sound-&gt;sound-&gt;getLength(&amp;length,FMOD_TIMEUNIT_PCM);
unsigned int readed=0;
unsigned int toread=datalen;
if(channel-&gt;position&gt;length) toread=0;

int pos=0;
memset(data,0,datalen);

soundtouch::SAMPLETYPE*out=(soundtouch::SAMPLETYPE*)data;
int outSamples=datalen/sizeof(soundtouch::SAMPLETYPE)/channels;
int prevSamples=-1;
do{
    int nSamples=0;
    int cnt=0;
    while(!touch.numSamples() &amp;&amp; !channel-&gt;atEnd){
        channel-&gt;locSystem-&gt;update();
    }
    int readySamples=touch.numSamples();
        nSamples=touch.receiveSamples(out,outSamples);
    if(nSamples==0 &amp;&amp; prevSamples==0) break; prevSamples=nSamples;
    out+=nSamples*channels;
    outSamples-=nSamples;
}while(outSamples&gt;0);

return FMOD_OK;

}

// Setup position to read data from source sound file/stream
FMOD_RESULT F_CALLBACK SoundChannel::pcmsetposcallback(FMOD_SOUND *fsound, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
{
FMOD::Sound *sound = (FMOD::Sound *)fsound;
SoundChannel *channel=0;
sound->getUserData((void**)&channel);

soundtouch::SoundTouch &amp;touch=channel-&gt;touch;
touch.clear();
int bps=4;
int channels=2;
int bits=32;
{
    //channel-&gt;sound-&gt;sound-&gt;getFormat(&amp;type,&amp;format,&amp;channels,&amp;bits);
    bps=bits*channels/8;
    touch.setChannels(channels);
    touch.setSampleRate(44100);
    channel-&gt;atEnd=false;
}
touch.setSetting(SETTING_USE_QUICKSEEK, true);
touch.setSetting(SETTING_USE_AA_FILTER, true);

qDebug()&lt;&lt;&quot;pcmsetpos &quot;&lt;&lt;position&lt;&lt;&quot; &quot;&lt;&lt;postype;
if(postype==FMOD_TIMEUNIT_PCM){
    channel-&gt;position=position;
}else{
    //TODO2
}
//TODO
{
    FMOD_RESULT result;
    FMOD_SOUND_TYPE  type;
    result=channel-&gt;locSystem-&gt;playSound(FMOD_CHANNEL_REUSE, channel-&gt;sound-&gt;sound, false, &amp;channel-&gt;locChannel);
    ERRCHECK(result);
    result=channel-&gt;locChannel-&gt;setPosition(position, postype);
    ERRCHECK(result);
    result=channel-&gt;locSystem-&gt;update();
    ERRCHECK(result);
}
return FMOD_OK;

}

// Start play the sound
void SoundChannel::play(){
FMOD::System *system=SoundSystem::fmodSystem();

FMOD::Sound            *asound;
FMOD_RESULT       result;
FMOD_CREATESOUNDEXINFO  createsoundexinfo;
memset(&amp;createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo.cbsize            = sizeof(FMOD_CREATESOUNDEXINFO);
createsoundexinfo.decodebuffersize  = 4096;
createsoundexinfo.length            = -1;
createsoundexinfo.numchannels       = 2;
createsoundexinfo.defaultfrequency  = 44100;
createsoundexinfo.format            = FMOD_SOUND_FORMAT_PCMFLOAT;
createsoundexinfo.pcmreadcallback   = pcmreadcallback;
createsoundexinfo.pcmsetposcallback = pcmsetposcallback;
createsoundexinfo.userdata=this;    
createsoundexinfo.initialseekposition=position;
createsoundexinfo.initialseekpostype=FMOD_TIMEUNIT_PCM;

//sound-&gt;sound-&gt;getFormat(0,&amp;createsoundexinfo.format,&amp;createsoundexinfo.numchannels,0);

startPosition=position;
result = system-&gt;createSound(0, FMOD_OPENUSER | FMOD_LOOP_NORMAL | FMOD_SOFTWARE|FMOD_CREATESTREAM, &amp;createsoundexinfo, &amp;asound);
atEnd=false;
ERRCHECK(result);

result = system-&gt;playSound(FMOD_CHANNEL_REUSE , asound, paused, &amp;channel);
//result = system-&gt;playSound(FMOD_CHANNEL_FREE , asound, paused, &amp;channel);
ERRCHECK(result);
channel-&gt;setUserData(this);
channel-&gt;setCallback(mycallback);
system-&gt;update();
updateTimer-&gt;start(100);

}

// Next functions are to control playng/pitch/tempo
void SoundChannel::setPaused(bool paused){
this->paused=paused;
if(channel){
FMOD_RESULT result;
result=channel->setPaused(paused);
ERRCHECK(result);
}
}

bool SoundChannel::isPaused() const{
if(channel){
FMOD_RESULT result;
bool paused=true;
result=channel->getPaused(&paused);
ERRCHECK(result);
return paused;
}
return false;
}
bool SoundChannel::isPlaying() const{
if(channel){
FMOD_RESULT result;
bool playing=true;
result=channel->isPlaying(&playing);
ERRCHECK(result);
return playing;
}
return false;
}

void SoundChannel::stop(){
if(channel){
updateTimer->stop();
FMOD_RESULT result;
result=channel->stop();
ERRCHECK(result);
}
}

void SoundChannel::setPosition(long pos){
if(pos==position) return;
position=pos;
startPosition=pos;

if(channel){
    FMOD_RESULT       result;
    result=channel-&gt;setPosition(pos,FMOD_TIMEUNIT_PCM);
    ERRCHECK(result);
}

}

long SoundChannel::getPosition() const{
if(channel && isPlaying()){
return position;
/FMOD_RESULT result;
unsigned int pos;
result=channel->getPosition(&pos,FMOD_TIMEUNIT_PCM);
ERRCHECK(result);
return pos;
/
}
return startPosition;
}

void SoundChannel::updatePosition(){
long pos=getPosition();
if(pos!=prevUpdatePos){
prevUpdatePos=pos;
emit positionChanged(pos);
}
}

void SoundChannel::setTempo(double a){
touch.setTempoChange(a);
}

void SoundChannel::setPitch(double a){
touch.setPitchSemiTones((float)a);
}
[/code:23t9fxle]

  • You must to post comments
0
0

thanks for your support

i’ll try to use this

/////////////////////////////////////////////////////////
[quote="cemehehko":89os8qen]I have solve this problem without setFrequency. I use SoundTouch (opensource library for partial pitch and tempo correction).

I use three features of FMOD:
1. Custom sound with my callbacks on readData and setPosition. This for send sound to output device.
2. Custom DSP. This for collect sound data from Sound.
3. NOSOUND_NRT. This for convert all sounds to single format (PCMFLOAT) to activate my custom DSP.

[code:89os8qen]

include "soundchannel.h"

include "WaveSound.h"

include "SoundSystem.h"

include <QTimer>

include <math.h>

include "SoundTouch/SoundTouch.h"

include <QMessageBox>

class WaveSound : public QObject
{
Q_OBJECT
public:
WaveSound(const QString &fileName);

long length();

protected:
FMOD::Sound *sound;
friend class SoundSystem;
friend class SoundChannel;
};

WaveSound::WaveSound(const QString &fileName)
{
FMOD_RESULT result;
FMOD_CREATESOUNDEXINFO exinfo;
FMOD_MODE mode = FMOD_2D | FMOD_OPENUSER;

    mode |= FMOD_LOOP_NORMAL;
    mode |= FMOD_SOFTWARE;

    memset(&amp;exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
    exinfo.cbsize           = sizeof(FMOD_CREATESOUNDEXINFO);
    exinfo.length           = 0;
    exinfo.numchannels      = 2;
    exinfo.defaultfrequency = 44100;
    exinfo.format           = FMOD_SOUND_FORMAT_PCMFLOAT;

// SoundSystem – is real soundsystem device.
result = SoundSystem::fmodSystem()->createStream(fileName.toLocal8Bit(), FMOD_2D|FMOD_SOFTWARE|FMOD_OPENONLY | FMOD_ACCURATETIME, &exinfo, &sound);
ERRCHECK(result);
}

long WaveSound::length(){
unsigned int len=0;
sound->getLength(&len,FMOD_TIMEUNIT_PCM);
return len;
}

class SoundChannel : public QObject
{
Q_OBJECT
public:
SoundChannel();
void setSound(WaveSound *sound);
bool isPaused() const;
bool isPlaying() const;
long getPosition() const;
public slots:
void play();
void setPaused(bool paused);
void stop();
void setPosition(long pos);

void setTempo(double a);
void setPitch(double a);

private slots:
void updatePosition();
signals:
void positionChanged(long pos);
protected:
static FMOD_RESULT F_CALLBACK SoundChannel::mycallback(FMOD_CHANNEL *fchannel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2);
static FMOD_RESULT F_CALLBACK SoundChannel::pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen);
static FMOD_RESULT F_CALLBACK SoundChannel::pcmsetposcallback(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype);

static FMOD_RESULT F_CALLBACK SoundChannel::DSPGetResultCallback(FMOD_DSP_STATE *pDspState,
     float *pInBuf,float *pOutBuf, unsigned int nSamples,
     int nInChannels, int nOutChannels);

WaveSound *sound;
FMOD::Channel* channel;
QTimer *updateTimer;
bool paused;
long startPosition;
long position;
bool atEnd;

soundtouch::SoundTouch touch;

FMOD::System *locSystem; // NO_SOUND ENGINE
FMOD::Channel* locChannel; // NO_SOUND CHANNEL

};

SoundChannel::SoundChannel()
{
FMOD_RESULT result;

sound=0;
channel=0;

locSystem=0;
locChannel=0;
atEnd=true;

updateTimer=new QTimer(this);
connect(updateTimer,SIGNAL(timeout()),SLOT(updatePosition()));
paused=false;
position=startPosition=0;

// Create NO_SOUND System Engine with a channel
result=FMOD::System_Create(&amp;locSystem);
ERRCHECK(result);
result=locSystem-&gt;setOutput(FMOD_OUTPUTTYPE_NOSOUND_NRT);
ERRCHECK(result);
result=locSystem-&gt;init(2, FMOD_INIT_NORMAL, NULL);
locSystem-&gt;setSoftwareFormat(44100,FMOD_SOUND_FORMAT_PCM16,FMOD_SPEAKERMODE_STEREO,0,FMOD_DSP_RESAMPLER_LINEAR);
ERRCHECK(result);
result=locSystem-&gt;setUserData(this);
ERRCHECK(result);

FMOD_DSP_DESCRIPTION  dspdesc;
FMOD::DSP *dsp;
memset(&amp;dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION));
strcpy(dspdesc.name, &quot;Get Result DSP unit&quot;);
dspdesc.channels = 0;
dspdesc.userdata=this;
qDebug()&lt;&lt;&quot;channel=&quot;&lt;&lt;this;
dspdesc.read = DSPGetResultCallback;
result=locSystem-&gt;createDSP(&amp;dspdesc, &amp;dsp);
ERRCHECK(result);
result=locSystem-&gt;addDSP(dsp,0);
ERRCHECK(result);

}

// DSP to collect sound data and send it to SoundTouch
// SOUND_NRT – is Not Real Time processing, System::update() cause this function
FMOD_RESULT F_CALLBACK SoundChannel::DSPGetResultCallback(FMOD_DSP_STATE *pDspState,
float *pInBuf,
float *pOutBuf,
unsigned int nSamples,
int nInChannels,
int nOutChannels) {
FMOD::DSP *dsp=(FMOD::DSP *)(pDspState->instance);
SoundChannel *channel=0;
dsp->getUserData((void**)&channel);

channel-&gt;touch.putSamples(pInBuf,nSamples);
channel-&gt;position+=nSamples;

return FMOD_OK;

}

void SoundChannel::setSound(WaveSound *sound){
this->sound=sound;
position=0;
emit positionChanged(position);
}

// Get sound data from SoundTouch
// If buffer is empty do NRT::update() to fill buffer.
FMOD_RESULT F_CALLBACK SoundChannel::pcmreadcallback(FMOD_SOUND *fsound, void *data, unsigned int datalen)
{
FMOD::Sound *sound = (FMOD::Sound *)fsound;
SoundChannel *channel=0;
sound->getUserData((void**)&channel);

soundtouch::SoundTouch &amp;touch=channel-&gt;touch;

int bps=1;
int channels=1;
int bits;
{
    FMOD_SOUND_TYPE  type;
    channel-&gt;sound-&gt;sound-&gt;getFormat(&amp;type,0,&amp;channels,&amp;bits);
    bps=bits*channels/8;
}

unsigned int length=0;
channel-&gt;sound-&gt;sound-&gt;getLength(&amp;length,FMOD_TIMEUNIT_PCM);
unsigned int readed=0;
unsigned int toread=datalen;
if(channel-&gt;position&gt;length) toread=0;

int pos=0;
memset(data,0,datalen);

soundtouch::SAMPLETYPE*out=(soundtouch::SAMPLETYPE*)data;
int outSamples=datalen/sizeof(soundtouch::SAMPLETYPE)/channels;
int prevSamples=-1;
do{
    int nSamples=0;
    int cnt=0;
    while(!touch.numSamples() &amp;&amp; !channel-&gt;atEnd){
        channel-&gt;locSystem-&gt;update();
    }
    int readySamples=touch.numSamples();
        nSamples=touch.receiveSamples(out,outSamples);
    if(nSamples==0 &amp;&amp; prevSamples==0) break; prevSamples=nSamples;
    out+=nSamples*channels;
    outSamples-=nSamples;
}while(outSamples&gt;0);

return FMOD_OK;

}

// Setup position to read data from source sound file/stream
FMOD_RESULT F_CALLBACK SoundChannel::pcmsetposcallback(FMOD_SOUND *fsound, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
{
FMOD::Sound *sound = (FMOD::Sound *)fsound;
SoundChannel *channel=0;
sound->getUserData((void**)&channel);

soundtouch::SoundTouch &amp;touch=channel-&gt;touch;
touch.clear();
int bps=4;
int channels=2;
int bits=32;
{
    //channel-&gt;sound-&gt;sound-&gt;getFormat(&amp;type,&amp;format,&amp;channels,&amp;bits);
    bps=bits*channels/8;
    touch.setChannels(channels);
    touch.setSampleRate(44100);
    channel-&gt;atEnd=false;
}
touch.setSetting(SETTING_USE_QUICKSEEK, true);
touch.setSetting(SETTING_USE_AA_FILTER, true);

qDebug()&lt;&lt;&quot;pcmsetpos &quot;&lt;&lt;position&lt;&lt;&quot; &quot;&lt;&lt;postype;
if(postype==FMOD_TIMEUNIT_PCM){
    channel-&gt;position=position;
}else{
    //TODO2
}
//TODO
{
    FMOD_RESULT result;
    FMOD_SOUND_TYPE  type;
    result=channel-&gt;locSystem-&gt;playSound(FMOD_CHANNEL_REUSE, channel-&gt;sound-&gt;sound, false, &amp;channel-&gt;locChannel);
    ERRCHECK(result);
    result=channel-&gt;locChannel-&gt;setPosition(position, postype);
    ERRCHECK(result);
    result=channel-&gt;locSystem-&gt;update();
    ERRCHECK(result);
}
return FMOD_OK;

}

// Start play the sound
void SoundChannel::play(){
FMOD::System *system=SoundSystem::fmodSystem();

FMOD::Sound            *asound;
FMOD_RESULT       result;
FMOD_CREATESOUNDEXINFO  createsoundexinfo;
memset(&amp;createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo.cbsize            = sizeof(FMOD_CREATESOUNDEXINFO);
createsoundexinfo.decodebuffersize  = 4096;
createsoundexinfo.length            = -1;
createsoundexinfo.numchannels       = 2;
createsoundexinfo.defaultfrequency  = 44100;
createsoundexinfo.format            = FMOD_SOUND_FORMAT_PCMFLOAT;
createsoundexinfo.pcmreadcallback   = pcmreadcallback;
createsoundexinfo.pcmsetposcallback = pcmsetposcallback;
createsoundexinfo.userdata=this;    
createsoundexinfo.initialseekposition=position;
createsoundexinfo.initialseekpostype=FMOD_TIMEUNIT_PCM;

//sound-&gt;sound-&gt;getFormat(0,&amp;createsoundexinfo.format,&amp;createsoundexinfo.numchannels,0);

startPosition=position;
result = system-&gt;createSound(0, FMOD_OPENUSER | FMOD_LOOP_NORMAL | FMOD_SOFTWARE|FMOD_CREATESTREAM, &amp;createsoundexinfo, &amp;asound);
atEnd=false;
ERRCHECK(result);

result = system-&gt;playSound(FMOD_CHANNEL_REUSE , asound, paused, &amp;channel);
//result = system-&gt;playSound(FMOD_CHANNEL_FREE , asound, paused, &amp;channel);
ERRCHECK(result);
channel-&gt;setUserData(this);
channel-&gt;setCallback(mycallback);
system-&gt;update();
updateTimer-&gt;start(100);

}

// Next functions are to control playng/pitch/tempo
void SoundChannel::setPaused(bool paused){
this->paused=paused;
if(channel){
FMOD_RESULT result;
result=channel->setPaused(paused);
ERRCHECK(result);
}
}

bool SoundChannel::isPaused() const{
if(channel){
FMOD_RESULT result;
bool paused=true;
result=channel->getPaused(&paused);
ERRCHECK(result);
return paused;
}
return false;
}
bool SoundChannel::isPlaying() const{
if(channel){
FMOD_RESULT result;
bool playing=true;
result=channel->isPlaying(&playing);
ERRCHECK(result);
return playing;
}
return false;
}

void SoundChannel::stop(){
if(channel){
updateTimer->stop();
FMOD_RESULT result;
result=channel->stop();
ERRCHECK(result);
}
}

void SoundChannel::setPosition(long pos){
if(pos==position) return;
position=pos;
startPosition=pos;

if(channel){
    FMOD_RESULT       result;
    result=channel-&gt;setPosition(pos,FMOD_TIMEUNIT_PCM);
    ERRCHECK(result);
}

}

long SoundChannel::getPosition() const{
if(channel && isPlaying()){
return position;
/FMOD_RESULT result;
unsigned int pos;
result=channel->getPosition(&pos,FMOD_TIMEUNIT_PCM);
ERRCHECK(result);
return pos;
/
}
return startPosition;
}

void SoundChannel::updatePosition(){
long pos=getPosition();
if(pos!=prevUpdatePos){
prevUpdatePos=pos;
emit positionChanged(pos);
}
}

void SoundChannel::setTempo(double a){
touch.setTempoChange(a);
}

void SoundChannel::setPitch(double a){
touch.setPitchSemiTones((float)a);
}
[/code:89os8qen][/quote:89os8qen]

  • You must to post comments
0
0

You can also choose another time-stretching libraries with this program technics:
1. DIRAC [url:3ek8rxgi]http://www.dspdimension.com/technology-licensing/dirac/[/url:3ek8rxgi] (FREE and Commertial closed sources.)
2. Rubber Band [url:3ek8rxgi]http://www.breakfastquay.com/rubberband/[/url:3ek8rxgi] (Free and Commertial open sources)
3. SoundToch (already)
4. etc..

SoundTouch is the simplest method. Quality of sound is not good.
I have try Rubber Band. Rubber Band is better. Rubber Band have no theoretical limitation for speedup/slowdown rate. SoundTouch are only 2 times.

Another problem is playPosition in orinal file. The simplest solution is to get buffered position but this is not accuracy(more than 100ms).

Please let me know what library you choose and how you solve problem with playing position.

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.