X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Faudiocontainer.cpp;h=70d5dd98e1ea2f88b35f51b60386b1eb3be2aac0;hb=c2813b4d63804cac9b4067146a9e6eca717cb3e4;hp=a5a9c929ca28a76f7f1081bb6d5b3ca623c804dd;hpb=ce408de81ca266b1f334ee9bc6c8fb7ba1492ed4;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp b/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp index a5a9c92..70d5dd9 100644 --- a/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp +++ b/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp @@ -2,7 +2,7 @@ /*! \file audiocontainer.cpp ** \brief Audio Container implementation File ** -** $Id: audiocontainer.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley @@ -54,6 +54,8 @@ #include #endif +#include "general.h" + #endif /* === U S I N G =========================================================== */ @@ -81,54 +83,58 @@ const double delay_factor = 3; struct FSOUND_SAMPLE; using studio::AudioContainer; +#ifdef WITH_FMOD bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector &samples) +#else +bool build_profile(FSOUND_SAMPLE */*sample*/, double &/*samplerate*/, std::vector &/*samples*/) +#endif { #ifdef WITH_FMOD - + float sps = samplerate; - + //trivial rejection... if(!sample || sps < 1) { synfig::warning("build_profile: Sample rate was too low or sample was invalid"); return false; } - + //lock for all samples and process them into a subset unsigned int mode = FSOUND_Sample_GetMode(sample); - + //make sure that it's 8 bit... I hope this works... - + //sample rate of the actual song... int allsamplerate = 0; FSOUND_Sample_GetDefaults(sample,&allsamplerate,0,0,0); - + //get the size of the sample defaults from the mode int channels = 1; int channelsize = 1; //number of bytes - + if(mode & FSOUND_16BITS) channelsize = 2; //this shouldn't happen if(mode & FSOUND_STEREO) channels = 2; - + //Get the sample information int samplesize = channels*channelsize; //the only two things that increase samplesize int numsamples = FSOUND_Sample_GetLength(sample); //number of samples in the sound int sizeall = samplesize*numsamples; //should be the size of the entire song... - + if(sizeall <= 0) { synfig::warning("ProfileAudio: Sample buffer cannot be size smaller than 1 (%X)",FSOUND_GetError()); return false; } - + //be sure that the new sample rate is less than or equal to the original if(sps > allsamplerate) sps = allsamplerate; - + float stride = allsamplerate/(float)sps; - - //down sampling to 8 bit min/max values + + //down sampling to 8 bit min/max values synfig::warning("About to downsample from %d Hz to %.1f Hz, sample stride: %f", allsamplerate, sps, stride); - + char *sampledata=0,*useless = 0; unsigned int len1,len2; // vector samples; @@ -139,27 +145,27 @@ bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector return false; } synfig::warning("Locked: %X: %d bytes, %X: %d bytes",sampledata,len1,useless,len2); - + if(channelsize == 1) { //process the data char *iter = sampledata; char *end = iter + sizeall; - + float curaccum = 0; float numinc = sps/(float)allsamplerate; - + /* Loop per sample DDA alg. */ - + int i = 0; - + //HACK - to prevent if statement inside inner loop //synfig::warning("wo baby wo baby, inc: %d, stride: %f, size: %d", inc, stride, sizeall); while(iter < end) { int maxs = 0, mins = 0; - + for(;curaccum < 1; curaccum += numinc) { for(i = 0; iter < end && i < channels; ++i, iter += channelsize) @@ -171,7 +177,7 @@ bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector //insert onto new list samples.push_back(maxs); samples.push_back(mins); - + //and flush all the used samples for curaccum curaccum -= 1; } @@ -180,21 +186,21 @@ bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector //process the data char *iter = sampledata; char *end = iter + sizeall; - + float curaccum = 0; float numinc = sps/(float)allsamplerate; - + /* Loop per sample DDA alg. */ - + int i = 0; - + //HACK - to prevent if statement inside inner loop //synfig::warning("wo baby wo baby, inc: %d, stride: %f, size: %d", inc, stride, sizeall); while(iter < end) { int maxs = 0, mins = 0; - + for(;curaccum < 1; curaccum += numinc) { for(i = 0; iter < end && i < channels; ++i, iter += channelsize) @@ -206,31 +212,31 @@ bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector //insert onto new list samples.push_back(maxs / 256); samples.push_back(mins / 256); - + //and flush all the used samples for curaccum curaccum -= 1; } } } - + synfig::warning("Stats: %f seconds with %d bytes now %d bytes", (samples.size()/2)/sps, sizeall, samples.size()); synfig::warning(" %f seconds before", numsamples/(float)allsamplerate); - + //we're done yay!, unlock FSOUND_Sample_Unlock(sample,sampledata,useless,len1,len2); synfig::info("Unlocked"); - + //FSOUND_PlaySound(FSOUND_FREE,sound); //test - + //we're done samplerate = sps*2; //it must be x2 because we are sampling max and min - + return true; - + #else - + return false; - + #endif } @@ -238,7 +244,7 @@ bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector //FMOD Systemwide Specific data mostly here... struct scrubinfo; - + #ifdef WITH_FMOD static double buffer_length_sec = 0; @@ -256,112 +262,112 @@ static double buffer_length_sec = 0; /* Things to check: If IsPlaying just governs the channel play/stop value or if it also concerns the pause state - + */ //so we can know where to create all this stuff struct scrubinfo { /* Linearly fit the frequency to hit the desired zero point... - */ + */ /*struct scrubelement { double pos; double dt; //the amount of time left til the cursor hits this one - // it's incremental so that the cursor must pass previous + // it's incremental so that the cursor must pass previous // ones before decrementing this value - }; + }; */ - + //the time it should take to get to the next position... - + //to prevent from writing to the same location at once... (pos, deltatime, delaystart) //Glib::Mutex lock; - + //the queue system would provide a more accurate representation... volatile double pos; volatile double deltatime; - + volatile double delaystart; //the amount of time we need to go before we start interpolating... - + volatile int channel; /*std::list queue; - + volatile int channel; - + //current position is FSOUND_GetCurrentPosition and current time is always 0... - + void add(const scrubelement &elem) { lock.LockWrite(); - + queue.push_back(elem); - + lock.UnlockWrite(); } - + //Function to safely get rid of all the old samples (dt < 0) void flush() { lock.LockWrite(); - + while(queue.size() && queue.front().dt < 0) { queue.pop_front(); } - - lock.UnlockWrite(); + + lock.UnlockWrite(); }*/ - + void Lock() { //lock.lock(); } - + void Unlock() { //lock.unlock(); } - + //All parameters and state should be set by the time we get here... void scrub_dsp_process() { const double epsilon = 1e-5; - + //Trivial reject... we go nowhere if we aren't playing (hit boundary...) if(!FSOUND_IsPlaying(channel)) return; - + //Get rid of all the old samples //flush(); - + //Trivial reject #2 - We also go nowhere with no future samples (pause) /*if(queue.size() <= 0) { FSOUND_SetPaused(channel,true); return; }*/ - + double dt = buffer_length_sec; - + //Lock ourselves so we don't die Lock(); - + //printf("DSP data: delay = %.3f s, pos = %d, dt = %.3f\n", delaystart, (int)pos, deltatime); - + //Check delay if(delaystart > 0) { delaystart -= dt; - + if(delaystart < 0) { dt = -delaystart; //add time back... delaystart = 0; } } - + //Trivial reject for if we're past current sample... if(delaystart > 0 || deltatime <= 0) { @@ -369,65 +375,65 @@ struct scrubinfo Unlock(); return; } - + //Calculate stretched frequency based on delayed future sample... - + //NOTE: BY NOT TRACKING POSITION AS A FLOAT AND JUST USING THE SOUNDS VALUE - // WE ARE LOSING A TINY AMOUNT OF PRECISION ACCURACY EVERY UPDATE + // WE ARE LOSING A TINY AMOUNT OF PRECISION ACCURACY EVERY UPDATE // (THIS SHOULDN'T BE A PROBLEM) - const double p0 = FSOUND_GetCurrentPosition(channel); + const double p0 = FSOUND_GetCurrentPosition(channel); double curdp = 0; - + if(!FSOUND_GetPaused(channel)) { curdp = FSOUND_GetFrequency(channel) * deltatime; } - //need to rescale derivative... + //need to rescale derivative... //Extrapolate from difference in position and deltatime vs dt... const double pa = p0 + curdp/2; - + const double p1 = pos; - + //const double pb = p0/3 + p1*2/3; - + //will extrapolate if needed... (could be funky on a curve) double t = 0; if(deltatime > epsilon) { t = dt / deltatime; } - + //Decrement deltatime (we may have gone past but that's what happens when we don't get input...) deltatime -= dt; - + //we don't need to look at the current variables anymore... Unlock(); - + const double invt = 1-t; //double deltapos = (p1-p0)*t; //linear version double deltapos = invt*invt*p0 + 2*t*invt*pa + t*t*p1 - p0; //quadratic smoothing version - + //Attempted cubic smoothing //const double invt2 = invt*invt; //const double t2 = t*t; //double deltapos = invt2*invt*p0 + 3*t*invt2*pa + 3*t2*invt*pb + t2*t*p1; //double deltapos = p0 + t*(3*(pa-p0) + t*(3*(p0+2*pa+pb) + t*((p1-3*pb+3*ba-p0)))); //unwound cubic - + //printf("\ttime = %.2f; p(%d,%d,%d) dp:%d - delta = %d\n",t,(int)p0,(int)p1,(int)p2,(int)curdp,(int)deltapos); - + //Based on the delta info calculate the stretched frequency const int dest_samplesize = FSOUND_DSP_GetBufferLength(); - + //rounded to nearest frequency... (hopefully...) int freq = (int)(deltapos * FSOUND_GetOutputRate() / (double)dest_samplesize); - + //NOTE: WE MIGHT WANT TO DO THIS TO BE MORE ACCURATE BUT YEAH... ISSUES WITH SMALL NUMBERS //double newdp = deltapos / t; //printf("\tfreq = %d Hz\n", freq); - + // !If I failed... um assume we have to pause it... ? if(abs(freq) < 100) { @@ -438,11 +444,11 @@ struct scrubinfo FSOUND_SetPaused(channel,false); if(!FSOUND_SetFrequency(channel,freq)) { - //ERROR WILL ROBINSON!!!... + //ERROR WILL ROBINSON!!!... printf("Error in Freq... what do I do?\n"); } } - } + } }; struct scrubuserdata @@ -452,24 +458,24 @@ struct scrubuserdata typedef scrubinfo** value_type; typedef std::set< value_type > scrubslist; scrubslist scrubs; - + //so we can lock access to the list... ReadWriteLock lock; - + void AddScrub(scrubinfo **i) { lock.LockWrite(); scrubs.insert(i); lock.UnLockWrite(); } - + void RemoveScrub(scrubinfo **i) { lock.LockWrite(); scrubs.erase(i); - lock.UnLockWrite(); + lock.UnLockWrite(); }*/ - + scrubinfo * volatile * scrub; }; @@ -484,20 +490,20 @@ void * scrubdspwrap(void *originalbuffer, void *newbuffer, int length, void *use if(userdata) { scrubuserdata &sd = *(scrubuserdata*)userdata; - + /* //For use with multiple scrubs... //Lock so no one can write to it while we're reading from it... sd.lock.LockRead(); - - //make a copy of it... + + //make a copy of it... std::vector v(sd.scrubs.begin(),sd.scrubs.end()); - + //other things can do stuff with it again... sd.lock.UnLockRead(); - - //loop through the list and process all the active scrub units + + //loop through the list and process all the active scrub units std::vector::iterator i = v.begin(), - end = v.end(); + end = v.end(); for(;i != end; ++i) { //check to make sure this object is active... @@ -507,15 +513,15 @@ void * scrubdspwrap(void *originalbuffer, void *newbuffer, int length, void *use } } */ - + if(sd.scrub && *sd.scrub) { //dsp += " processing..."; - scrubinfo * info = (*sd.scrub); + scrubinfo * info = (*sd.scrub); info->scrub_dsp_process(); } } - + //synfig::info(dsp); return newbuffer; @@ -527,63 +533,63 @@ class FMODInitializer { bool loaded; int refcount; - + public: FMODInitializer():loaded(false),refcount(0) {} - ~FMODInitializer() + ~FMODInitializer() { clear(); } - + void addref() { if(!loaded) { #ifdef WITH_FMOD synfig::info("Initializing FMOD on demand..."); - + { FSOUND_SetOutput(AUDIO_OUTPUT); - + /*int numdrivers = FSOUND_GetNumDrivers(); synfig::info("Num FMOD drivers = %d",numdrivers); synfig::info("Current Driver is #%d", FSOUND_GetDriver()); - + for(int i = 0; i < numdrivers; ++i) { unsigned int caps = 0; FSOUND_GetDriverCaps(i,&caps); - + synfig::info(" Caps for driver %d (%s) = %x",i,FSOUND_GetDriverName(i),caps); } - + FSOUND_SetDriver(0);*/ - + //Modify buffer size... //FSOUND_SetBufferSize(100); - + if(!FSOUND_Init(44100, 32, 0)) { synfig::warning("Unable to load FMOD"); }else { loaded = true; - + //Create the DSP for processing scrubbing... scrubdspunit = FSOUND_DSP_Create(&scrubdspwrap,default_scrub_priority,&g_scrubdata); - + //Load the number of sec per buffer into the global variable... buffer_length_sec = FSOUND_DSP_GetBufferLength() / (double)FSOUND_GetOutputRate(); } } #endif } - + //add to the refcount ++refcount; //synfig::info("Audio: increment fmod refcount %d", refcount); } - + void decref() { if(refcount <= 0) @@ -593,20 +599,20 @@ public: { --refcount; //synfig::info("Audio: decrement fmod refcount %d", refcount); - + //NOTE: UNCOMMENT THIS IF YOU WANT FMOD TO UNLOAD ITSELF WHEN IT ISN'T NEEDED ANYMORE... flush(); } } bool is_loaded() const { return loaded; } - + void clear() { refcount = 0; flush(); } - + void flush() { if(loaded && refcount <= 0) @@ -614,7 +620,7 @@ public: #ifdef WITH_FMOD synfig::info("Unloading FMOD"); if(scrubdspunit) FSOUND_DSP_Free(scrubdspunit); - FSOUND_Close(); + FSOUND_Close(); #endif loaded = false; } @@ -653,48 +659,52 @@ double studio::AudioProfile::get_offset() const //---------- AudioContainer definitions --------------------- struct studio::AudioContainer::AudioImp -{ +{ //Sample load time information FSOUND_SAMPLE * sample; int channel; int sfreq; int length; - + //Time information double offset; //time offset for playing... - + //We don't need it now that we've adopted the play(t) time schedule... - //current time... and playing info.... + //current time... and playing info.... //float seekpost; //bool useseekval; - + //Make sure to sever our delayed start if we are stopped prematurely sigc::connection delaycon; - + //Action information bool playing; double curscrubpos; etl::clock timer; //for getting the time diff between scrub input points - + //Scrubbing information... //the current position of the sound will be sufficient for normal stuff... #ifdef WITH_FMOD scrubinfo scrinfo; #endif - + scrubinfo *scrptr; - + bool is_scrubbing() const {return scrptr != 0;} +#ifdef WITH_FMOD void set_scrubbing(bool s) +#else + void set_scrubbing(bool /*s*/) +#endif { #ifdef WITH_FMOD if(s) scrptr = &scrinfo; - else + else #endif scrptr = 0; } - + //helper to make sure we are actually playing (and to get a new channel...) bool init_play() { @@ -717,14 +727,14 @@ struct studio::AudioContainer::AudioImp FSOUND_SetFrequency(channel,sfreq); } return true; - + #else - + return false; - + #endif } - + public: //structors AudioImp() :sample(0), @@ -733,19 +743,19 @@ public: //structors length(0), offset(0), playing(false), - scrptr(0) + scrptr(0) { //reuse the channel... #ifdef WITH_FMOD channel = FSOUND_FREE; #endif } - + ~AudioImp() { clear(); } - + public: //helper/accessor funcs bool start_playing_now() //callback for timer... { @@ -757,10 +767,10 @@ public: //helper/accessor funcs FSOUND_SetPaused(channel,false); } #endif - + return false; //so the timer doesn't repeat itself - } - + } + bool isRunning() { #ifdef WITH_FMOD @@ -769,59 +779,63 @@ public: //helper/accessor funcs return false; #endif } - + bool isPaused() - { + { #ifdef WITH_FMOD return FSOUND_GetPaused(channel); #else return false; #endif } - - + + public: //forward interface - + //Accessors for the offset - in seconds const double &get_offset() const {return offset;} - void set_offset(const double &d) + void set_offset(const double &d) { offset = d; } - + //Will override the parameter timevalue if the sound is running, and not if it's not... +#ifdef WITH_FMOD bool get_current_time(double &out) +#else + bool get_current_time(double &/*out*/) +#endif { if(isRunning()) { #ifdef WITH_FMOD unsigned int pos = FSOUND_GetCurrentPosition(channel); - + //adjust back by 1 frame... HACK.... //pos -= FSOUND_DSP_GetBufferLength(); - + //set the position out = pos/(double)sfreq + offset; #endif - + return true; } return false; } - + //Big implementation functions... bool load(const std::string &filename, const std::string &filedirectory); void clear(); - + //playing functions void play(double t); void stop(); - + //scrubbing functions void start_scrubbing(double t); void scrub(double t); void stop_scrubbing(); - + double scrub_time() { return curscrubpos; @@ -839,44 +853,48 @@ studio::AudioContainer::~AudioContainer() if(imp) delete (imp); } -bool studio::AudioContainer::load(const string &filename,const string &filedirectory) +bool studio::AudioContainer::load(const std::string &filename,const std::string &filedirectory) { if(!imp) { imp = new AudioImp; } - + profilevalid = false; return imp->load(filename,filedirectory); } +#ifdef WITH_FMOD handle studio::AudioContainer::get_profile(float samplerate) +#else +handle studio::AudioContainer::get_profile(float /*samplerate*/) +#endif { #ifdef WITH_FMOD - + //if we already have done our work, then we're good if(profilevalid && prof) { //synfig::info("Using already built profile"); return prof; } - + //synfig::info("Before profile"); //make a new profile at current sample rate - - //NOTE: We might want to reuse the structure already there... + + //NOTE: We might want to reuse the structure already there... prof = new AudioProfile; prof->set_parent(this); //Our parent is THIS!!! - + if(!prof) { synfig::warning("Couldn't allocate audioprofile..."); return handle(); } - + //setting the info for the sample rate //synfig::info("Setting info..."); - + synfig::info("Building Profile..."); prof->samplerate = samplerate; if(build_profile(imp->sample,prof->samplerate,prof->samples)) @@ -888,25 +906,25 @@ handle studio::AudioContainer::get_profile(float samplerat { return handle(); } - + #else - + return handle(); - + #endif } void studio::AudioContainer::clear() { - if(imp) + if(imp) { delete imp; imp = 0; } - + profilevalid = false; } - + void studio::AudioContainer::play(double t) { if(imp) imp->play(t); @@ -938,14 +956,14 @@ double AudioContainer::get_offset() const bool AudioContainer::is_playing() const { - if(imp) + if(imp) return imp->playing; return false; } bool AudioContainer::is_scrubbing() const { - if(imp) + if(imp) return imp->is_scrubbing(); return false; } @@ -985,19 +1003,24 @@ bool AudioContainer::isPaused() const //----------- Audio imp information ------------------- -bool studio::AudioContainer::AudioImp::load(const std::string &filename, +#ifdef WITH_FMOD +bool studio::AudioContainer::AudioImp::load(const std::string &filename, const std::string &filedirectory) +#else +bool studio::AudioContainer::AudioImp::load(const std::string &/*filename*/, + const std::string &/*filedirectory*/) +#endif { clear(); #ifdef WITH_FMOD - + //And continue with the sound loading... string file = filename; - + //Trivial reject... (fixes stat call problem... where it just looks at directory and not file...) if(file.length() == 0) return false; - + //we don't need the file directory? if(!is_absolute_path(file)) { @@ -1005,117 +1028,121 @@ bool studio::AudioContainer::AudioImp::load(const std::string &filename, synfig::warning("Not absolute hoooray"); } synfig::info("Loading Audio file: %s", file.c_str()); - + //check to see if file exists { struct stat s; if(stat(file.c_str(),&s) == -1 && errno == ENOENT) { - synfig::info("There was no audio file..."); + synfig::info("There was no audio file..."); return false; } } - + //load fmod if we can... //synfig::warning("I'm compiled with FMOD!"); fmodinit.addref(); - + //load the stream int ch = FSOUND_FREE; FSOUND_SAMPLE *sm = FSOUND_Sample_Load(FSOUND_FREE,file.c_str(),FSOUND_LOOP_OFF|FSOUND_MPEGACCURATE,0,0); - + if(!sm) { synfig::warning("Could not open the audio file as a sample: %s",file.c_str()); goto error; } - + //synfig::warning("Opened a file as a sample! :)"); - + /*{ int bufferlen = FSOUND_DSP_GetBufferLength(); synfig::info("Buffer length = %d samples, %.3lf s",bufferlen, bufferlen / (double)FSOUND_GetOutputRate()); }*/ - + //set all the variables since everything has worked out... //get the length of the stream { length = FSOUND_Sample_GetLength(sm); - + int volume = 0; FSOUND_Sample_GetDefaults(sm,&sfreq,&volume,0,0); - - //double len = length / (double)sfreq; + + //double len = length / (double)sfreq; //synfig::info("Sound info: %.2lf s long, %d Hz, %d Vol",(double)length,sfreq,volume); } - + //synfig::warning("Got all info, and setting up everything, %.2f sec.", length); //synfig::warning(" BigSample: composed of %d samples", FSOUND_Sample_GetLength(sm)); synfig::info("Successfully opened %s as a sample and initialized it.",file.c_str()); - + //set up the playable info sample = sm; channel = ch; - + //the length and sfreq params have already been initialized - + return true; - + error: if(sm) FSOUND_Sample_Free(sm); file = ""; - + fmodinit.decref(); - + return false; - + #else return false; #endif } +#ifdef WITH_FMOD void studio::AudioContainer::AudioImp::play(double t) +#else +void studio::AudioContainer::AudioImp::play(double /*t*/) +#endif { #ifdef WITH_FMOD if(!sample) return; - + //stop scrubbing if we are... if(is_scrubbing()) stop_scrubbing(); - + //t -= offset; t -= get_offset(); playing = true; - + if(t < 0) { unsigned int timeout = (int)floor(-t * 1000 + 0.5); //synfig::info("Playing audio delayed by %d ms",timeout); //delay for t seconds... delaycon = Glib::signal_timeout().connect( - sigc::mem_fun(*this,&studio::AudioContainer::AudioImp::start_playing_now),timeout); - + sigc::mem_fun(*this,&studio::AudioContainer::AudioImp::start_playing_now),timeout); + init_play(); FSOUND_SetFrequency(channel,sfreq); FSOUND_SetCurrentPosition(channel,0); return; } - + unsigned int position = (int)floor(t*sfreq + 0.5); - + if(position >= FSOUND_Sample_GetLength(sample)) { synfig::warning("Can't play audio when past length..."); return; } - + init_play(); FSOUND_SetFrequency(channel,sfreq); FSOUND_SetCurrentPosition(channel,position); FSOUND_SetPaused(channel,false); - + //synfig::info("Playing audio with position %d samples",position); - - #endif + + #endif } void studio::AudioContainer::AudioImp::stop() @@ -1124,11 +1151,11 @@ void studio::AudioContainer::AudioImp::stop() #ifdef WITH_FMOD if(fmodinit.is_loaded() && playing && isRunning()) - { + { FSOUND_SetPaused(channel,true); } #endif - + playing = false; } @@ -1136,10 +1163,10 @@ void studio::AudioContainer::AudioImp::clear() { #ifdef WITH_FMOD delaycon.disconnect(); - + stop(); stop_scrubbing(); - + if(sample) { if(FSOUND_IsPlaying(channel)) @@ -1150,97 +1177,105 @@ void studio::AudioContainer::AudioImp::clear() FSOUND_Sample_Free(sample); fmodinit.decref(); } - + playing = false; - + #else channel = 0; #endif - + sample = 0; - playing = false; + playing = false; } -void AudioContainer::AudioImp::start_scrubbing(double t) +#ifdef WITH_FMOD +void studio::AudioContainer::AudioImp::start_scrubbing(double t) +#else +void studio::AudioContainer::AudioImp::start_scrubbing(double /*t*/) +#endif { //synfig::info("Start scrubbing: %lf", t); if(playing) stop(); - + set_scrubbing(true); - + #ifdef WITH_FMOD //make sure the other one is not scrubbing... if(g_scrubdata.scrub) { *g_scrubdata.scrub = 0; //nullify the pointer... } - + //Set up the initial state for the delayed audio position scrinfo.delaystart = 0; scrinfo.pos = 0; scrinfo.deltatime = 0; - + //set it to point to our pointer (dizzy...) g_scrubdata.scrub = &scrptr; //setup position info so we can know what to do on boundary conditions... curscrubpos = (t - get_offset()) * sfreq; - + //So we can get an accurate difference... timer.reset(); - - //reposition the sound if it won't be when scrubbed (if it's already in the range...) + + //reposition the sound if it won't be when scrubbed (if it's already in the range...) int curi = (int)curscrubpos; if(curi >= 0 && curi < length) { init_play(); FSOUND_SetCurrentPosition(channel,curi); - + //Set the values... scrinfo.pos = curscrubpos; scrinfo.delaystart = delay_factor*buffer_length_sec; - + //synfig::info("\tStarting at %d samps, with %d p %.3f delay", // FSOUND_GetCurrentPosition(channel), (int)scrinfo.pos, scrinfo.delaystart); } - - - + + + //enable the dsp... //synfig::info("\tActivating DSP"); FSOUND_DSP_SetActive(scrubdspunit,true); #endif } -void AudioContainer::AudioImp::stop_scrubbing() +void studio::AudioContainer::AudioImp::stop_scrubbing() { //synfig::info("Stop scrubbing"); - + if(is_scrubbing()) { set_scrubbing(false); - + #ifdef WITH_FMOD g_scrubdata.scrub = 0; - + //stop the dsp... //synfig::info("\tDeactivating DSP"); FSOUND_DSP_SetActive(scrubdspunit,false); if(FSOUND_IsPlaying(channel)) FSOUND_SetPaused(channel,true); #endif } - + curscrubpos = 0; } -void AudioContainer::AudioImp::scrub(double t) +#ifdef WITH_FMOD +void studio::AudioContainer::AudioImp::scrub(double t) +#else +void studio::AudioContainer::AudioImp::scrub(double /*t*/) +#endif { #ifdef WITH_FMOD //synfig::info("Scrub to %lf",t); if(is_scrubbing()) - { + { //What should we do? - + /* Different special cases All outside, all inside, coming in (left or right), @@ -1248,10 +1283,10 @@ void AudioContainer::AudioImp::scrub(double t) */ double oldpos = curscrubpos; double newpos = (t - get_offset()) * sfreq; - + curscrubpos = newpos; - - //Ok the sound is running, now we need to tweek it + + //Ok the sound is running, now we need to tweak it if(newpos > oldpos) { //Outside so completely stopped... @@ -1268,19 +1303,19 @@ void AudioContainer::AudioImp::scrub(double t) scrinfo.delaystart = 0; scrinfo.deltatime = 0; scrinfo.Unlock(); - + return; } - + //going in? - start the sound at the beginning... /*else if(oldpos < 0) { //Set up the sound to be playing paused at the start... init_play(); FSOUND_SetCurrentPosition(channel,0); - + synfig::info("\tIn + %d", FSOUND_GetCurrentPosition(channel)); - + scrinfo.Lock(); scrinfo.pos = 0; scrinfo.delaystart = delay_factor*buffer_length_sec; @@ -1288,21 +1323,21 @@ void AudioContainer::AudioImp::scrub(double t) scrinfo.Unlock(); }*/ //don't need to deal with leaving... automatically dealt with... - + else //We're all inside... { //Set new position and decide what to do with time... scrinfo.Lock(); scrinfo.pos = newpos; - - //should we restart the delay cycle... (is it done?) + + //should we restart the delay cycle... (is it done?) if(!isRunning() || (scrinfo.delaystart <= 0 && scrinfo.deltatime <= 0 && isPaused())) { //synfig::info("Starting + at %d",(int)newpos); scrinfo.deltatime = 0; scrinfo.delaystart = delay_factor*buffer_length_sec; scrinfo.Unlock(); - + //Set up the sound paused at the current position init_play(); int setpos = min(max((int)newpos,0),length); @@ -1310,17 +1345,17 @@ void AudioContainer::AudioImp::scrub(double t) timer.reset(); return; } - + //No! just increment the time delta... scrinfo.deltatime += timer.pop_time(); - + //Nope... continue and just increment the deltatime and reset position... scrinfo.Unlock(); - + //set channel and unpause FSOUND_SetPaused(channel,false); scrinfo.channel = channel; - + } }else if(newpos < oldpos) { @@ -1332,22 +1367,22 @@ void AudioContainer::AudioImp::scrub(double t) { FSOUND_SetPaused(channel,true); } - + //Zero out the data! scrinfo.Lock(); scrinfo.delaystart = 0; scrinfo.deltatime = 0; scrinfo.Unlock(); } - + //going in? - start going backwards at the end... /*else if(oldpos >= length) { synfig::info("In -"); //Set up the sound to be playing paused at the start... init_play(); - FSOUND_SetCurrentPosition(channel,length-1); - + FSOUND_SetCurrentPosition(channel,length-1); + scrinfo.Lock(); scrinfo.pos = length-1; scrinfo.delaystart = delay_factor*buffer_length_sec; @@ -1355,35 +1390,35 @@ void AudioContainer::AudioImp::scrub(double t) scrinfo.Unlock(); }*/ //we don't have to worry about the leaving case... - + else //We're all inside... { //Set new position and decide what to do with time... scrinfo.Lock(); scrinfo.pos = newpos; - - //should we restart the delay cycle... (is it done?) + + //should we restart the delay cycle... (is it done?) if(!isRunning() ||(scrinfo.delaystart <= 0 && scrinfo.deltatime <= 0 && isPaused())) { //synfig::info("Starting - at %d",(int)newpos); scrinfo.deltatime = 0; scrinfo.delaystart = delay_factor*buffer_length_sec; scrinfo.Unlock(); - - //reset timing so next update will be a valid diff... + + //reset timing so next update will be a valid diff... init_play(); int setpos = min(max((int)newpos,0),length); FSOUND_SetCurrentPosition(channel,setpos); timer.reset(); return; } - + //No! just increment the time delta... scrinfo.deltatime += timer.pop_time(); - + //Nope... continue and just increment the deltatime and reset position... scrinfo.Unlock(); - + //set channel and unpause FSOUND_SetPaused(channel,false); scrinfo.channel = channel;