[Amis-vcs] SF.net SVN: amis: [2382] branches/amis3/AmisGuiMFC2
Brought to you by:
julienq,
marisademeglio
From: <dan...@us...> - 2008-03-03 04:44:55
|
Revision: 2382 http://amis.svn.sourceforge.net/amis/?rev=2382&view=rev Author: daniel_weck Date: 2008-03-02 20:45:01 -0800 (Sun, 02 Mar 2008) Log Message: ----------- missing files !!! Modified Paths: -------------- branches/amis3/AmisGuiMFC2/src/gui/self-voicing/AudioSequencePlayer.cpp Added Paths: ----------- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/directshow/ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/directshow/dx_audio_player.h branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/SmilTimeCode.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/counter.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/field.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounter.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounterArray.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/timeCode.H branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/win32fix.H branches/amis3/AmisGuiMFC2/src/gui/self-voicing/directshow/ branches/amis3/AmisGuiMFC2/src/gui/self-voicing/directshow/dx_audio_player.cpp Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/directshow/dx_audio_player.h =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/directshow/dx_audio_player.h (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/directshow/dx_audio_player.h 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,223 @@ +/* + * This file is part of Ambulant Player, www.ambulantplayer.org. + * + * Copyright (C) 2003-2008 Stichting CWI, + * Kruislaan 413, 1098 SJ Amsterdam, The Netherlands. + * + * Ambulant Player is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * Ambulant Player is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Ambulant Player; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * @$Id: dx_audio_player.h,v 1.21 2008/01/15 10:54:48 jackjansen Exp $ + */ + +#ifndef AMBULANT_GUI_DX_AUDIO_PLAYERX_H +#define AMBULANT_GUI_DX_AUDIO_PLAYERX_H + +//#include "ambulant/config/config.h" + +#include <string> +#include <cmath> + +#include <objbase.h> +#include <strmif.h> +#include <control.h> + +#include <initguid.h> + +//#include "ambulant/common/playable.h" +//#include "ambulant/lib/win32/win32_error.h" +//#include "ambulant/lib/logger.h" + +/* +#ifdef _DEBUG +#pragma comment(lib, "msvcrtd.lib") +#else +#pragma comment(lib, "msvcrt.lib") +#endif +*/ + +/* +#ifndef AMBULANT_PLATFORM_WIN32_WCE +#pragma comment (lib,"winmm.lib") +#pragma comment (lib,"amstrmid.lib") +#endif +#pragma comment (lib,"strmiids.lib") +#pragma comment (lib,"uuid.lib") +*/ + +#ifndef AMBULANT_PLATFORM_WIN32_WCE +#define WITH_TPB_AUDIO_SPEEDUP +#endif + +#ifdef WITH_TPB_AUDIO_SPEEDUP +// If this option is active during build (which is true when building +// for AmisAmbulant) we try to insert the TPB Audio Speedup/Slowdown +// filter into our filtergraph. This allows for changing audio playback +// speed without altering pitch. +// If the TPB DirectShow filter is not available we do nothing. +#include <set> + +DEFINE_GUID(CLSID_TPBVupp69, + 0x66172967, 0x56c5, 0x4b89, 0xaa, 0x92, 0xc9, 0xef, 0xec, 0x56, 0x46, 0x7b); + + +#ifdef __cplusplus +extern "C" { +#endif + +// {A33E626E-D6C4-4559-A1D6-9F1D95F0D8E2} +DEFINE_GUID(IID_IVuppInterface, +0xa33e626e, 0xd6c4, 0x4559, 0xa1, 0xd6, 0x9f, 0x1d, 0x95, 0xf0, 0xd8, 0xe2); + +DECLARE_INTERFACE_(IVuppInterface, IUnknown) { + + //Deklarera metoder: + STDMETHOD(setCrossFadeSpeed) + ( THIS_ + double speed + ) PURE; + + STDMETHOD(setWindowLength) + ( THIS_ + int length + ) PURE; + + STDMETHOD(setCycleSpeed) + ( THIS_ + short speed + ) PURE; + + STDMETHOD(setSilenceLoudnessThreshold) + ( THIS_ + short threshold + ) PURE; + + STDMETHOD(setSilenceRemainderLength) + ( THIS_ + short length + ) PURE; + + STDMETHOD(setSilenceSpeed) + ( THIS_ + short speed + ) PURE; + + STDMETHOD(getPosition) + ( THIS_ + LONGLONG &position + ) PURE; +}; + +#ifdef __cplusplus +} +#endif + + + +#endif // WITH_TPB_AUDIO_SPEEDUP + +typedef void (*sendMessageCallbackFn)(void); + +static double s_current_playback_rate = 1.0; + +namespace ambulantX { + +namespace gui { + +namespace dx { + +class audio_playerX { + + typedef std::pair<bool, double> duration; + + public: + + audio_playerX(); + void setCallback(sendMessageCallbackFn pFunction); + + static audio_playerX* Instance(); + static void DestroyInstance(); + + ~audio_playerX(); + + void start(double t); + void stop(bool fromPlay, bool fromThread=false); + //void pause(common::pause_display d=common::display_show); + void pause(void); + void resume(); + void seek(double t); + void endseek(double t); + duration get_dur(); + void wantclicks(bool want) {} + void preroll(double when, double where, double how_much) {} + + bool can_play(); + bool is_playing(); + double get_position(); + + // -val is the attenuation in decibels + // can be 0 to 100 + void set_volume(long val); + + // can be -100 to 100 + // 0 sets a neutral balance + // and 10 sets -10 db to right and -90 db to left + void set_balance(long val); + bool play(const char * url); + + private: + + void end_thread(); + + void release_player(); + + std::string m_url; + + IGraphBuilder *m_graph_builder; + IMediaControl *m_media_control; + IMediaPosition *m_media_position; + IBasicAudio *m_basic_audio; + + HANDLE hEventHandler; + +public: + IMediaEvent *m_media_event; + sendMessageCallbackFn sendMessageCallback; + +private: + + CRITICAL_SECTION m_csSequence; + static audio_playerX* pinstance; + +#ifdef WITH_TPB_AUDIO_SPEEDUP + public: + void set_rate(double rate); + double get_rate(); + + private: + IVuppInterface *m_audio_speedup; + void initialize_speedup_filter(); +#endif +}; + +} // namespace dx + +} // namespace gui + +} // namespace ambulantX + +#endif // AMBULANT_GUI_DX_AUDIO_PLAYERX_H + Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/SmilTimeCode.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/SmilTimeCode.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/SmilTimeCode.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,209 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000-2005 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef SMILTIMECODE_H_ +#define SMILTIMECODE_H_ + +#define SMILTIMECODE_VERSION 0.0 + +#include "timeCode.H" +#include <strstream> +//#include "win32fix.H" + +//Begins the implementation of SMIL timing : +// http://www.w3.org/TR/2005/REC-SMIL2-20050107/smil-timing.html#Timing-LanguageDefinition + +//The array type is char so that it can contain a smil mark up of a time reference +#define ARRAYTYPE char +//There are four fields in smil ... hours, minutes, seconds and milliseconds +#define FIELDCOUNT 4 +//The master counter will not work with X under win32 so for portability, use no GUI - field +#define MASTERCOUNTERTYPE MasterCounter<field, FIELDCOUNT> +//The maximum field counts +#define MAX_HOURS 300 +#define MAX_MINUTES 60 +#define MAX_SECONDS 60 +#define MAX_MILLISECONDS 1000 + +#define DEFAULTBUFLEN 512 + +/** This class loads a TimeCode structure with the correct + beginning and end. A SMIL type of string is used as input for + both times + +*/ +class SmilTimeCode : public TimeCode<MASTERCOUNTERTYPE, ARRAYTYPE> { + + //This function performs the raw string to milliseconds conversion + //Input is a SMIL compliant string + //Output is a millisecond count. + int convertStrToTimeCode(char *strSMIL){ + //Step for conversion : + // Work out the time metric : this correcponds to the maximum specified time field + // Work out whether the last field is a fractional part and remember that info. + // Hold fields in an array 'counts' + // Load a master counter with appropriate millisecond count + // Return the master counter millisecond count + + //Find the metric and thus the end of the stream + //Form an array to hold the metric digit values + int startMetric=0; + + char * tempI; + if ((tempI=strstr(strSMIL,"ms"))!=NULL){ + //we are receiving milliseconds + tempI[0]='\0'; //Mark a new end to the string + startMetric=0; //Indicate the start metric + } else if ((tempI=strstr(strSMIL,"s"))!=NULL){ + //we are receiving seconds + tempI[0]='\0'; //Mark a new end to the string + startMetric=1; //Indicate the start metric + } else if ((tempI=strstr(strSMIL,"min"))!=NULL){ + //we are receiving minutes + tempI[0]='\0'; //Mark a new end to the string + startMetric=2; //Indicate the start metric + } else if ((tempI=strstr(strSMIL,"h"))!=NULL){ + //we are receiving hours + tempI[0]='\0'; //Mark a new end to the string + startMetric=3; //Indicate the start metric + } else { + //No specification of metric. + // Check number of ':' in the string + int cnt=0; + for (int i=0;i<strlen(strSMIL);i++){ + if (strSMIL[i]==':') + cnt++; + } + if (cnt==3)//We are using hours minutes seconds milliseconds + startMetric=3; + else if (cnt==2)//We are using hours minutes seconds + startMetric=3; + else if (cnt==1)//We are using minutes seconds + startMetric=2; + else //We are using seconds + startMetric=1; + } + + cout<<"startMetric="<<startMetric<<endl; + + //Make sure '.' is translated to ':' + float convertLastField=0; //Use this to force fractional conversion of the smallest field + if ((tempI=strstr(strSMIL,"."))!=NULL){ + convertLastField=atof(tempI); + tempI[0]=':'; + cout<<convertLastField<<endl; + } + //if (convertLastField) + // cout<<"Last field needs conversion"<<endl; + + //Form an array to hold values counts[4]={milliseconds, sec, min, hours} + int counts[4]={-1,-1,-1,-1}; + + //Fill up to the start metric with zeros + for (int i=FIELDCOUNT-1;i>startMetric;i--) + counts[i]=0; + + /* for (i=0;i<FIELDCOUNT;i++) + cout<<counts[i]<<'\t'; + cout<<endl; + */ + + int howMany, howManyNot, origStartMetric; //Indicates how many tokens (and non tokens) + parseTok:{ + howMany=howManyNot=0; + origStartMetric=startMetric; + + //Work out how many tokens to parse + istrstream buf(strSMIL); + char tempS[DEFAULTBUFLEN]; + while (buf.getline(tempS,DEFAULTBUFLEN,':')){//Fill the array from the end + if (strlen(tempS)){ //Guard against no first token e.g. .25 (meaning 0.25 seconds) + howMany++; + if (startMetric>=0) + counts[startMetric]=atoi(tempS); + //cout<<tempS<<'\t'<<counts[startMetric]<<endl;; + } else { + howManyNot++; + if (startMetric>=0) + counts[startMetric]=0; + } + startMetric--; + } + cout<<howMany<<" Fields"<<endl; + } + + if (origStartMetric+1<howMany){ + cout<<"metric (h,min,s or ms) doesn't match the number of fields, autocorrecting"<<endl; + startMetric=howMany-1; + goto parseTok; + } + + for (i=0;i<FIELDCOUNT;i++) + cout<<counts[i]<<'\t'; + cout<<endl; + + //Now load up the masterCounter + MASTERCOUNTERTYPE tempTime (128,MAX_HOURS,MAX_MINUTES,MAX_SECONDS,MAX_MILLISECONDS); + tempTime=0; + int factor=1,fractionalFactor=1;//Factor to multiply by + //tempTime.dump(); + for (i=0;i<FIELDCOUNT;i++){ + switch (i) { + case 0: factor=1; fractionalFactor*=MAX_MILLISECONDS; + break; + case 1: factor*=MAX_MILLISECONDS; fractionalFactor*=MAX_SECONDS; + break; + case 2: factor*=MAX_SECONDS; fractionalFactor*=MAX_MINUTES; + break; + case 3: factor*=MAX_MINUTES; break; + default: cout<<"SmilTimeCode::convertStrToTimeCode field count exceeded : Error 2"<<endl; break; + } + if (counts[i]>=0){ //Check that a token exists + if (convertLastField>0){ //We must use a fractional concept + //cout<<"fractional i="<<i<<" counts[i]="<<counts[i]<<" fractionalFactor = "<<fractionalFactor<<endl; + //char tempS[DEFAULTBUFLEN]; + //sprintf(tempS,"0.%d\0",counts[i]); + //tempTime+=atof(tempS)*fractionalFactor; + //cout<<"fractional i="<<i<<" convertLastField="<<convertLastField<<" fractionalFactor = "<<fractionalFactor<<endl; + tempTime+=convertLastField*(fractionalFactor+1); //Check this +1 : introduced to remove 1ms error e.g. 0.120 goes to 0.119 without this +1 + convertLastField=0; //Ensure it doesn't happen again. + } else //Regular update + tempTime+=counts[i]*factor; + } + } + + // tempTime.dump(); + + return tempTime.getCount(); + } + +public: + //The time code is restricted to MAX_INT hours, 60 minutes, 60 seconds and 1000 milliseconds + SmilTimeCode(char *SMILBegin, char *SMILCurrent, char *SMILEnd) : TimeCode<MASTERCOUNTERTYPE, ARRAYTYPE>(DEFAULTBUFLEN,MAX_HOURS,MAX_MINUTES,MAX_SECONDS,MAX_MILLISECONDS){ + //This constructor will fill in the time code for beginning, current time and end time + + //Set the end of time + //setFinish(convertStrToTimeCode(SMILEnd)); + this->end=convertStrToTimeCode(SMILEnd); + //Set the beginning of time + //setBeginning(convertStrToTimeCode(SMILBegin)); + this->start=convertStrToTimeCode(SMILBegin); + } +}; +#endif //SMILTIMECODE_H_ Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/counter.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/counter.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/counter.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,172 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000, 2001 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef COUNTER_H_ +#define COUNTER_H_ + +//#include <iomanip.h> +#include <iostream> + +#ifndef MAXINT +#include "./win32fix.h" +#endif + +//#define C_DEBUG + +//#define CTYPE int +class counter { +protected: + inline void cond(void){ +#ifdef C_DEBUG + std::cout<<"counter::cond enter"<<std::endl; +#endif + if (minCount<(int)0.0) + std::cerr<<"Warning: min Count < 0 and may cause problems"<<std::endl; + if (maxCount<=minCount) + std::cerr<<"Warning: max Count <= min Count and may cause problems"<<std::endl; + if (maxCount==(int)0.0) + std::cerr<<"Warning: max Count = 0 and may cause problems"<<std::endl; + int temp=(int)0.0; + if (--temp>0){ + std::cerr<<"counter: You are using an unsigned type ... error ... exiting"<<std::endl; + exit(-1); + } +#ifdef C_DEBUG + std::cout<<"counter::cond exit"<<std::endl; +#endif + } + + inline void clean(void){ +#ifdef C_DEBUG + std::cout<<"counter::clean count = "<<count<<std::endl; +#endif + int tempCount=count-minCount, tempMaxCount=maxCount-minCount; + // std::cout<<tempCount<<'\t'<<tempMaxCount<<std::endl; + // if (count<0.0){ + // carry=count/maxCount-(int)1.0; + //count+=maxCount; + if (tempCount<0.0){ + carry=tempCount/tempMaxCount-(int)1.0; + tempCount+=tempMaxCount; + // std::cout<<carry<<'\t'<<count<<std::endl; + } + if (tempCount>=tempMaxCount){ + carry=tempCount/tempMaxCount; + tempCount%=tempMaxCount; + } + count=tempCount+minCount; + //std::cout<<"clean exit"<<std::endl; +#ifdef C_DEBUG + std::cout<<"counter::clean exit "<<count<<std::endl; +#endif + } + + int count, maxCount, minCount; + int carry; +public: + counter (){ +#ifdef C_DEBUG + std::cout<<"counter::counter()"<<std::endl; +#endif + maxCount=MAXINT; minCount=0; count=(int)0;carry=0; cond(); + + } + counter (int minc, int maxc){ +#ifdef C_DEBUG + std::cout<<"counter::counter(minc, maxc)"<<std::endl; +#endif + maxCount=maxc; minCount=minc; count=(int)0;carry=0; cond(); + } + counter (int minc, int c, int maxc){ +#ifdef C_DEBUG + std::cout<<"counter::counter(minc="<<minc<<", c="<<c<<", maxc="<<maxc<<")"<<std::endl; +#endif + // if (c<0.0) std::cout <<"counter: init vals must be >=0 ... this may cause a problem"<<std::endl; + count=c; maxCount=maxc; minCount=minc; carry=0; cond(); clean(); + } + + /// returns the current count + int getCount(void){return count;} + /// returns the maximum count + int getMaxCount(void){return maxCount;} + /// Sets the maximum count + int setMaxCount(counter mc){return setMaxCount(mc.count);} + int setMaxCount(int mc){ + if (count>mc) count=mc-1; + return maxCount=mc; + } + /// returns the minimum count + int getMinCount(void){return minCount;} + /// Sets the minimum count + int setMinCount(counter mc){return setMinCount(mc.count);} + int setMinCount(int mc){ +#ifdef C_DEBUG + std::cout<<"counter::setMinCount(mc="<<mc<<")"<<std::endl; +#endif + if (count<mc) count=mc; + return minCount=mc; + } + /// returns the carry + int getCarry(void){return carry;} + /// resets the carry to zero + void resetCarry(void){carry=0;} + + // Logic operators + char operator!=(counter& c) {return count != c.count;} + char operator!=(int& c) {return count != c;} + char operator==(counter& c) {return count == c.count;} + char operator==(int& c) {return count == c;} + char operator> (counter& c) {return count > c.count;} + char operator> (int& c) {return count > c;} + char operator>=(counter& c) {return count >= c.count;} + char operator>=(int& c) {return count >= c;} + char operator< (counter& c) {return count < c.count;} + char operator< (int& c) {return count < c;} + char operator<=(counter& c) {return count <= c.count;} + char operator<=(int& c) {return count <= c;} + + // Evaluational operators + counter& operator =(counter c){ + //std::cout<<"count::yoyo"<<std::endl; + count = c.count; clean(); return *this;} + counter& operator =(int c){ + //std::cout<<"count::yo "<<count<<std::endl; + count = c;clean(); return *this;} + counter& operator+=(counter c){count += c.count; clean(); return *this;} + counter& operator+=(int c){count += c; clean(); return *this;} + counter& operator-=(counter c){count -= c.count; clean(); return *this;} + counter& operator-=(int c){count -= c; clean(); return *this;} + counter& operator*=(counter c){count *= c.count; clean(); return *this;} + counter& operator*=(int c){count *= c; clean(); return *this;} + counter& operator/=(counter c){count /= c.count; clean(); return *this;} + counter& operator/=(int c){count /= c; clean(); return *this;} + + int operator+(counter& c){return count+c.count;} + int operator+(int c){return count+c;} + int operator-(counter& c){return count-c.count;} + int operator-(int c){return count-c;} + double operator*(counter& c){return (double)count*(double)c.count;} + double operator*(int c){return (double)count*(double)c;} + double operator/(counter& c){return (double)count/(double)c.count;} + double operator/(int c){return (double)count/(double)c;} + + friend std::ostream& operator <<(std::ostream& o, counter c) {o << c.count<<"\tcarry="<<c.carry<<"\tMinCount="<<c.minCount<<"\tMaxCount="<<c.maxCount; return o;} +}; +#endif //COUNTER_H_ + Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/field.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/field.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/field.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,108 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000, 2001 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef FIELD_H_ +#define FIELD_H_ + +#include <math.h> + +#include "counter.H" + +//template <class FTYPE> +//#define FTYPE int +class field : public counter { + unsigned int digitCount; + + /// Sets the digit count and display array + void countDigits(void){ + // Work out the required digit count ... + double mVal=maxCount; + digitCount=0; + while (mVal>pow(10.0,(int) ++digitCount)-1.0); + // Set up the digit array ... + digits=NULL; + if (!(digits=new unsigned char[digitCount])){ + std::cerr <<"field: digit malloc error"<<std::endl; + exit(-1); + } + } + + /// Sets the digits array to the digit value of the counter + void syncDigits(void){ + //std::cout<<"syncdigits :: "<<std::endl; + if (count==maxCount) count=0; + int cnt = count; + register double temp; + for (int i=digitCount-1;i>=0;i--){ + temp=pow(10.0, i); + digits[i]=(char)((double)cnt/temp); + //std::cout<<(int)digits[i]<<std::endl; + cnt-=digits[i]*(int)temp; + } + } + +public: + unsigned char *digits; + + field(int minimumVal, int startVal, int maximumVal) : counter(minimumVal, startVal, maximumVal){ +//#if DEBUG > 1 +// std::cout<<"field::field(minimumVal, startVal, maximumVal)"<<std::endl; +//#endif + digits=NULL; + // Set up the digit array and count + countDigits(); + // Sync the digits with the counter value + syncDigits(); + } + + ~field(void){ +//#if DEBUG > 1 +// std::cout<<"field::~field"<<std::endl; +//#endif + // std::cout<<"~field: in"<<std::endl; + if (digits) delete [] digits; + // std::cout<<"~field: out"<<std::endl; + } + + // The following alter the counter and must be overloaded + field& operator =(const counter& f){counter::operator =(f); syncDigits(); return *this;} + field& operator =(const int f){ + // std::cout<<"equate"<<std::endl; +counter::operator =(f); +//std::cout<<"about to sync"<<std::endl; + syncDigits(); return *this;} + field& operator+=(const counter& f){counter::operator+=(f); syncDigits(); return *this;} + field& operator+=(const int& f){counter::operator+=(f); syncDigits(); return *this;} + field& operator-=(const counter& f){counter::operator-=(f); syncDigits(); return *this;} + field& operator-=(const int& f){counter::operator-=(f); syncDigits(); return *this;} + field& operator*=(const counter& f){counter::operator*=(f); syncDigits(); return *this;} + field& operator*=(const int& f){counter::operator*=(f); syncDigits(); return *this;} + field& operator/=(const counter& f){counter::operator/=(f); syncDigits(); return *this;} + field& operator/=(const int& f){counter::operator/=(f); syncDigits(); return *this;} + + friend std::ostream& operator <<(std::ostream& o, field& f) { + std::cout<<(counter)f<<":\t"; + for (int i=f.digitCount-1; i>=0; i--) + o << (long)f.digits[i]; + return o; + } + + int digitCnt(void){return digitCount;} +}; +#endif //FIELD_H_ Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounter.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounter.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounter.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,194 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000, 2001 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef MASTERCOUNTER_H_ +#define MASTERCOUNTER_H_ + +#include <stdarg.h> +#include "field.H" + +//#define DEBUG_MC + +template <class FIELDTYPE, int FIELDCOUNT> +class MasterCounter : public counter { +protected: + FIELDTYPE **fields; +public: + int fieldCount(void){return FIELDCOUNT;} + + MasterCounter(int startVal, ...) : counter(0, startVal, 1){ +#ifdef DEBUG_MC + std::cout<<"MasterCounter::MasterCounter(startVal, ...)"<<std::endl; +#endif + int maxC=1; + + if (FIELDCOUNT){ + if (!(fields=new FIELDTYPE*[FIELDCOUNT])){ + std::cerr<<"MasterCounter: Out of memory error"<<std::endl; + exit(-1); + } + for (int i=0;i<FIELDCOUNT;i++) + fields[i]=NULL; + + va_list ap; + va_start(ap, startVal); + for (i=0;i<FIELDCOUNT;i++){ + int temp=va_arg(ap, int); + if (i==0) + maxC*=temp; + maxC*=temp; + if (!(fields[i]=new FIELDTYPE(0, 0,temp))){ + std::cerr<<"MasterCounter: Out of memory error 1"<<std::endl; + exit(-1); + } + } + va_end(ap); + setMaxCount(maxC); + updateFields(); + } +#ifdef DEBUG_MC + std::cout<<"MasterCounter::MasterCounter(startVal, ...) EXIT"<<std::endl; +#endif + } + + MasterCounter(void) : counter(0, 0, 1){ +#ifdef DEBUG_MC + std::cout<<"MasterCounter::MasterCounter()"<<std::endl; +#endif + if (FIELDCOUNT){ + fields=new FIELDTYPE*[FIELDCOUNT]; + if (!fields){ + std::cerr<<"MasterCounter: Out of memory error"<<std::endl; + exit(-1); + } + for (int i=0;i<FIELDCOUNT;i++) + fields[i]=NULL; + } + } + + void init(int c, ...){ +#ifdef DEBUG_MC + std::cout<<"MasterCount: init "<<c<<" ..."<<std::endl; +#endif + va_list ap; + va_start(ap, c); + init(c, ap); + va_end(ap); + } + + void init(int c, va_list& ap){ +#ifdef DEBUG_MC + std::cout<<"MasterCount: init "<<c<<std::endl; +#endif + count=c; + int maxC=1; + for (int i=0;i<FIELDCOUNT;i++){ + int temp=va_arg(ap, int); + maxC*=temp; + //std::cout<<i<<" after "<<temp<<'\t'<<maxC<<std::endl; + fields[i]=new FIELDTYPE(0,0,temp); + if (!fields[i]){ + std::cerr<<"MasterCounter: Out of memory error 1"<<std::endl; + exit(-1); + } + // std::cout<<FIELDCOUNT<< " looping"<<std::endl; + } + setMaxCount(maxC); + updateFields(); + } + + ~MasterCounter(void){ +#ifdef DEBUG_MC + std::cout<<"MasterCounter::~MasterCounter"<<std::endl; +#endif + if (fields) { + for (int i=0;i<FIELDCOUNT;i++){ + if (fields[i]) delete fields[i]; + fields[i]=NULL; + } + delete [] fields; + fields=NULL; + } + // std::cout<<"~MasterCounter: out"<<std::endl; + } + + /// Sets the minimum count + int setMinCount(counter mc){return setMinCount(mc.getCount());} + int setMinCount(int mc){ +#ifdef DEBUG_MC + std::cout<<"MasterCounter::setMinCount(mc="<<mc<<")"<<std::endl; +#endif + int temp=counter::setMinCount(mc); + updateFields(); + return temp; + } + + /// Sets the minimum count + int setMaxCount(counter mc){return setMaxCount(mc.getCount());} + int setMaxCount(int mc){ +#ifdef DEBUG_MC + std::cout<<"MasterCounter::setMaxCount(mc="<<mc<<")"<<std::endl; +#endif + int temp=counter::setMaxCount(mc); + updateFields(); + return temp; + } + + // syncs the field with the new counter value + void updateFields(void){ + //std::cout<<"masterCounter: updateFields"<<std::endl; + int temp=count, tempCarry; + for (int i=0;i<FIELDCOUNT;i++){ + //std::cout<<i<<std::endl; + int which =FIELDCOUNT-i-1; + tempCarry=temp%fields[which]->getMaxCount(); + temp=temp/fields[which]->getMaxCount(); + *fields[which]=(int)tempCarry; + } + //std::cout<<"masterCounter: updateFields EXIT"<<std::endl; + } + + // Logic operators + /* char operator==(counter& m) {return count == m.getCount();} + char operator!=(counter& m) {return count != m.getCount();} + char operator> (counter& m) {return count > m.getCount();} + char operator>=(counter& m) {return count >= m.getCount();} + char operator< (counter& m) {return count < m.getCount();} + char operator<=(counter& m) {return count <= m.getCount();} + */ + + // Evaluational operators + MasterCounter& operator =(counter c){counter::operator=(c); updateFields();return *this;} + MasterCounter& operator =(int c){counter::operator=(c);updateFields();return *this;} + MasterCounter& operator+=(counter c){counter::operator+=(c); updateFields();return *this;} + MasterCounter& operator+=(int c){counter::operator+=(c);updateFields();return *this;} + MasterCounter& operator-=(counter c){counter::operator-=(c); updateFields();return *this;} + MasterCounter& operator-=(int c){counter::operator-=(c); updateFields();return *this;} + MasterCounter& operator*=(counter c){counter::operator*=(c); updateFields();return *this;} + MasterCounter& operator*=(int c){counter::operator*=(c); updateFields();return *this;} + MasterCounter& operator/=(counter c){counter::operator/=(c); updateFields();return *this;} + MasterCounter& operator/=(int c){counter::operator/=(c); updateFields();return *this;} + + friend std::ostream& operator <<(std::ostream& o, MasterCounter<FIELDTYPE, FIELDCOUNT>& c) { + o << c.count<<"\tMinCount="<<c.minCount<<"\tcarry="<<c.carry<<"\tMaxCount="<<c.maxCount<<'\t'; + return o; + } +}; +#endif //MASTERCOUNTER_H_ + Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounterArray.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounterArray.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/masterCounterArray.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,163 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000, 2001 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef MASTERCOUNTERARRAY_H_ +#define MASTERCOUNTERARRAY_H_ + +#include <stdarg.h> +//#include <sys/resource.h> +#include "field.H" + +//#define MCA_DEBUG + +template <class MASTERCOUNTERTYPE, class ARRAYTYPE> +class MasterCounterArray : public MASTERCOUNTERTYPE { + + /// The size in bytes of a single sample (multichannel size). i.e. 16 bit stereo => 4 bytes + int frameSize; + // double countToFrames, framesToCount; + +protected: + ARRAYTYPE *array; +public: + // double getFramesToCount(){return framesToCount;} + //double getCountToFrames(){return countToFrames;} + + int getFrameSize(){return frameSize;} + int setFrameSize(int fsz){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::setFrameSize"<<std::endl; +#endif + //// Find the conversion from frames to count + // framesToCount=(double)frameCount/(double)rate; + //countToFrames=(double)rate/(double)frameCount; + + if (frameSize!=fsz){ + frameSize=fsz; + updateArray(); + } + return frameSize; + } + + /** Constructor, specifying a startValue for the array index and a + list of time code fields. + */ + MasterCounterArray(int startVal, ...) : MASTERCOUNTERTYPE(){ +#ifdef MCA_DEBUG + + std::cout<<"MasterCounterArray::MasterCounterArray(startVal="<<startVal<<", ...)"<<std::endl; +#endif + array=NULL; + frameSize=1; + va_list ap; + va_start(ap, startVal); + init(startVal, ap); + va_end(ap); + } + + /** Empty constructor, must use init to complete valid construction + */ + MasterCounterArray(void) : MASTERCOUNTERTYPE(){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::MasterCounterArray()"<<std::endl; +#endif + array=NULL; + frameSize=1; + } + + /** Initialiser for the empty constructor + */ + void init(int c, ...){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::init(startVal="<<c<<", ...)"<<std::endl; +#endif + va_list ap; + va_start(ap, c); + init(c, ap); + va_end(ap); + } + + /** second stage init, called by 'other' init function + */ + void init(int c, va_list& ap){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::init(startVal="<<c<<", va_list)"<<std::endl; +#endif + //cout<<"c "<<c<<endl; + MASTERCOUNTERTYPE::init(c,ap); + //std::cout<<*this<<std::endl; + updateArray(); + } + + /** Deconstructor */ + ~MasterCounterArray(void){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::~MasterCounterArray"<<std::endl; +#endif + if (array) delete [] array; + array=NULL; + // std::cout<<"MasterCounterArray::~MasterCounterArray exit"<<std::endl; + } + + void updateArray(){ +#ifdef MCA_DEBUG + std::cout<<"MasterCounterArray::updateArray - new size "<<getCount()*frameSize<<std::endl; +#endif + //std::cout<<"count "<<getCount()<<std::endl; + //std::cout<<"frameSize "<<frameSize<<std::endl; + if (array) delete [] array; + array=NULL; + // std::cout<<getCount()<<std::endl; + //Should limit the possible allocatable space here ... + /* struct rlimit limit; + getrlimit(RLIMIT_MEMLOCK , &limit); + std::cout<<"rlim_cur "<<limit.rlim_cur<<std::endl; + std::cout<<"rlim_max "<<limit.rlim_max<<std::endl; + */ + //cout<<"making array of size "<<this->getCount()*frameSize<<endl; + if (!(array=new ARRAYTYPE[this->getCount()*frameSize])){ + std::cout<<"MasterCounterArray: Out of memory"<<std::endl; + exit(-1); + } + //std::cout<<"MasterCounterArray::updateArray : array="<<array<<std::endl; + } + + void zeroArray(void){ + //Check whether this needs frameSize multiplier. + bzero(array, this->getCount()*sizeof(ARRAYTYPE)); + } + + // Evaluational operators + MasterCounterArray& operator =(counter c){counter::operator=(c); updateArray();return *this;} + MasterCounterArray& operator =(int c){counter::operator=(c);updateArray();return *this;} + MasterCounterArray& operator+=(counter c){counter::operator+=(c); updateArray();return *this;} + MasterCounterArray& operator+=(int c){counter::operator+=(c); updateArray();return *this;} + MasterCounterArray& operator-=(counter c){counter::operator-=(c); updateArray();return *this;} + MasterCounterArray& operator-=(int c){counter::operator-=(c); updateArray();return *this;} + MasterCounterArray& operator*=(counter c){counter::operator*=(c); updateArray();return *this;} + MasterCounterArray& operator*=(int c){counter::operator*=(c); updateArray();return *this;} + MasterCounterArray& operator/=(counter c){counter::operator/=(c); updateArray();return *this;} + MasterCounterArray& operator/=(int c){counter::operator/=(c); updateArray();return *this;} + + // ARRAYTYPE& operator[](int i){return array[i];} + ARRAYTYPE* getDataPtr(void){return array;} + ARRAYTYPE& operator[](int i){return array[i];} + // ARRAYTYPE& operator[]=(int i, ARRAYTYPE val){return array[i]=val;} +}; +#endif //MASTERCOUNTERARRAY_H_ Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/timeCode.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/timeCode.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/timeCode.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,220 @@ +/* + mffm Time Code + Time Code for multimedia systems + + Copyright (C) 2000, 2001 Matt R. Flax <fl...@ie...> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You have received a copy of the GNU Lesser General Public License + along with this library. +*/ +#ifndef TIMECODE_H_ +#define TIMECODE_H_ + +#include <stdarg.h> +#include "masterCounter.H" +#include "masterCounterArray.H" + +/** Time Code, inherits the current code + */ +template <class MASTERCOUNTERTYPE, class ARRAYTYPE> +class TimeCode : public MASTERCOUNTERTYPE { + int beginning, finish; +protected: + MASTERCOUNTERTYPE start, end; +public: + // The window count + MasterCounterArray<MASTERCOUNTERTYPE, ARRAYTYPE> *window; + //void zeroArray(void) {window->zeroArray();} + //ARRAYTYPE* getDataPtr(void){return window->getDataPtr();} + // ARRAYTYPE& operator[](int i){return window[i];} + + TimeCode(int startVal, ...) : MASTERCOUNTERTYPE (){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::TimeCode(startVal, ...)"<<std::endl; +//#endif + window=NULL; + va_list ap, ap1, ap2, ap3; + va_start(ap, startVal); + va_start(ap1, startVal); + va_start(ap2, startVal); + va_start(ap3, startVal); + init(startVal, ap, ap1, ap2, ap3); + va_end(ap); + va_end(ap1); + va_end(ap2); + va_end(ap3); + } + + TimeCode(void) : MASTERCOUNTERTYPE (){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::TimeCode()"<<std::endl; +//#endif + window=NULL; + } + + void init(int startVal, ...) { + va_list ap, ap1, ap2, ap3; + va_start(ap, startVal); + va_start(ap1, startVal); + va_start(ap2, startVal); + va_start(ap3, startVal); + init(startVal, ap, ap1, ap2, ap3); + va_end(ap); + va_end(ap1); + va_end(ap2); + va_end(ap3); + } + + void init(int c, va_list& ap, va_list& apStart, va_list& apEnd, va_list& apWindow){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::init"<<std::endl; +//#endif + beginning=0; + start.init(beginning, apStart); + + MASTERCOUNTERTYPE::init(c, ap); + finish=this->getMaxCount(); + + // Ensure end points to the last window + end.init(finish-1, apEnd); + + if (window) delete window; + if (!(window=new MasterCounterArray<MASTERCOUNTERTYPE, ARRAYTYPE>)) std::cerr <<"TimeCode::init : window malloc error"<<std::endl; + window->init(this->fields[this->fieldCount()-1]->getMaxCount(), apWindow); + } + + ~TimeCode(void){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::~TimeCode"<<std::endl; +//#endif + if (window) delete window; + } + + int getBeginning(void){return beginning;} + void setBeginning(counter c){setBeginning(c.getCount());} + void setBeginning(int c){ + if (c>=finish) + c=finish-1; + beginning=c; + setStart(beginning); + } + + void nothing(){} + + int getStart(){return start.getCount();}; + void setStart(counter c){setStart(c.getCount());} + void setStart(int c){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::setStart "<<c<<std::endl; +//#endif + //Check that the beginning is not underrun + // the end minimum is not before the start + // the end minimum matches the start point + if (c<beginning) c=beginning; + if (c>end.getCount()) c=end.getCount(); + // if (c<end->getMinCount()) end->setMinCount(c); + end.setMinCount(c); + nothing(); + start.MASTERCOUNTERTYPE::operator=(c);// set the start point + //start=c;// set the start point + // std::cout<<start<<std::endl; + setMinCount(start); // reset the minimum of the current time + } + + int getEnd(){return end.getCount();}; + void setEnd(counter c){setEnd(c.getCount());} + void setEnd(int c){ +//#if DEBUG > 1 +// std::cout<<"TimeCode::setEnd "<<c<<std::endl; +//#endif + + //Check that the finish is not overrun + // the start maximum is not after the end + // the start maximum matches the end point + if (c>finish) c=finish; + if (c<start.getCount()) c=start.getCount(); + + start.setMaxCount(c); + // set the end point + end.MASTERCOUNTERTYPE::operator=(c); + setMaxCount(end); // reset the maximum of the current time + } + + int getFinish(void){return finish;} + void setFinish(counter c){setEnd(c.getCount());} + void setFinish(int c){ + finish=c; + end.setMaxCount(c); + window->setMaxCount(c); + } + + /** this function will apply a type II filter using the masterArray as the + output. + Filter coefficients are specified by the arrays a and b, with their + coefficient counts represented by aCnt and bCnt. + The input is pointed to by 'input'. The current location must be pointed + to and there must be at least 'aCnt' elements in the array preceeding + the pointer. + This function will only process one output at a time. + Coefficient notes : + a[0]=1.0; + input : + input The current value of the input signal + aCnt the number of denomiator coefficients + a the denominator (pole polynomial) coefficients + bCnt the number of numerator coefficients + b the numerator (zero polynomial) coefficients + memory the filter memory of dimension max(aCnt,bCnt) + */ + inline void filter(ARRAYTYPE input, const int aCnt, const double *a, const int bCnt, const double *b, double *memory){ + int j, loc=this->getCount(); + + //cout<<a<<'\t'<<b<<'\t'<<memory<<'\n'; + //cout<<aCnt<<'\t'<<bCnt<<'\n'; + + // Firstly calculate the output + (*window)[loc]=input*b[0]+memory[0]; + //cout<<(*window)[loc]<<'\t'<<input<<'\t'<<b[0]<<'\t'<<memory[0]<<'\n'; + // Manipulate the filter memory + for (j=1;j<aCnt & j<bCnt; j++){ + memory[j-1]=memory[j]+input*b[j]-(*window)[loc]*a[j]; + //cout<<memory[j-1]<<'\t'<<memory[j]<<'\t'<<input<<'\t'<<b[j]<<'\t'<<(*window)[loc]<<'\t'<<a[j]<<'\n'; + } + + //if (bCnt>aCnt) + for (j;j<bCnt;j++){ + memory[j-1]=memory[j]+input*b[j]; + //cout<<"take 2 b: "<<memory[j-1]<<'\t'<<memory[j]<<'\t'<<input<<'\t'<<b[j]<<'\n'; + } + //else + for (j;j<aCnt;j++){ + memory[j-1]=memory[j]-(*window)[loc]*a[j]; + //cout<<"take 2 a "<<memory[j-1]<<'\t'<<memory[j]<<'\t'<<(*window)[loc]<<'\t'<<a[j]<<'\n'; + } + //cout<<'\n'; + } + + TimeCode& operator =(TimeCode& c){counter::operator=(c);return *this;} + TimeCode& operator =(counter c){counter::operator=(c);return *this;} + TimeCode& operator =(int c){counter::operator=(c);return *this;} + + friend std::ostream& operator <<(std::ostream& o, TimeCode& tc) { + o<<"TimeCode: Beginning: "<<tc.beginning<<" Finish: "<<tc.finish<<'\n'; + o<<"Start: "<<tc.start<<'\n'; + o<<"Current: "<<(MASTERCOUNTERTYPE&)tc<<'\n'; + o<<"End: "<<tc.end<<'\n'; + o<<"Window Count: "<<*tc.window<<'\n'; + return o; + } +}; +#endif //TIMECODE_H_ Added: branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/win32fix.H =================================================================== --- branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/win32fix.H (rev 0) +++ branches/amis3/AmisGuiMFC2/include/gui/self-voicing/mffmTimeCode/win32fix.H 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,74 @@ +/* Copyright 2001 Matt Flax <fl...@ie...> + This file is part of MFFM Time Scale Modification for Audio. + + MFFM Time Scale Modification for Audio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + MFFM Time Scale Modification for Audio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You have received a copy of the GNU General Public License + along with MFFM Time Scale Modification for Audio + */ +#ifndef WIN32FIX_H_ +#define WIN32FIX_H_ + +// DLLs in Windows should use the standard calling convention +#ifndef ADR_CALL + #if defined(WIN32) || defined(_WIN32) + #define ADR_CALL __stdcall + #else + #define ADR_CALL + #endif +#endif + +// Export functions from the DLL +#ifndef ADR_DECL +# if defined(WIN32) || defined(_WIN32) +# ifdef LIBFFT_EXPORTS +# define ADR_DECL __declspec(dllexport) +# else +# define ADR_DECL __declspec(dllimport) +# endif +# else +# define ADR_DECL +# endif +#endif + +#define ADR_FUNCTION(ret) extern "C" ADR_DECL ret ADR_CALL + +#ifndef round +#define round(a) roundD(a) +#endif + +#ifndef bzero +#define bzero(a,c) memset(a,0,c) +#endif + +#ifndef remainder +#define remainder(a,b) fmod(a,b) +#endif + +#ifndef MAXDOUBLE +//#include <limits> +//#define MAXDOUBLE (numeric_limits<double>::max()) +//#define MAXDOUBLE DBL_MAX +#define MAXDOUBLE 1e308 +#endif + +#ifndef MAXINT +//#include <limits> +//#define MAXINT (numeric_limits<int>::max()) +#define MAXINT INT_MAX +#endif + +#ifndef cerr +#include <iostream> +using namespace std; +//#define cerr std:cout +#endif +#endif Modified: branches/amis3/AmisGuiMFC2/src/gui/self-voicing/AudioSequencePlayer.cpp =================================================================== --- branches/amis3/AmisGuiMFC2/src/gui/self-voicing/AudioSequencePlayer.cpp 2008-03-03 04:23:41 UTC (rev 2381) +++ branches/amis3/AmisGuiMFC2/src/gui/self-voicing/AudioSequencePlayer.cpp 2008-03-03 04:45:01 UTC (rev 2382) @@ -295,6 +295,7 @@ } void AudioSequencePlayer::Play(AudioSequence* audioSequence, bool doNotRegisterInHistory) { + //Stop(); { #ifdef CCS_ACTIVE EnterCriticalSection(&m_csSequence); Added: branches/amis3/AmisGuiMFC2/src/gui/self-voicing/directshow/dx_audio_player.cpp =================================================================== --- branches/amis3/AmisGuiMFC2/src/gui/self-voicing/directshow/dx_audio_player.cpp (rev 0) +++ branches/amis3/AmisGuiMFC2/src/gui/self-voicing/directshow/dx_audio_player.cpp 2008-03-03 04:45:01 UTC (rev 2382) @@ -0,0 +1,696 @@ +// This file is part of Ambulant Player, www.ambulantplayer.org. +// +// Copyright (C) 2003-2008 Stichting CWI, +// Kruislaan 413, 1098 SJ Amsterdam, The Netherlands. +// +// Ambulant Player is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// Ambulant Player is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Ambulant Player; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +/* +* @$Id: dx_audio_player.cpp,v 1.22 2008/01/15 10:55:59 jackjansen Exp $ +*/ + +#ifndef __AFXWIN_H__ +#include <afxwin.h> +#endif + +#include "gui/self-voicing/directshow/dx_audio_player.h" + +//#include "ambulant/lib/logger.h" +//#include "ambulant/lib/textptr.h" +#include <math.h> +#include <vfwmsgs.h> +// CLSID_FilterGraph +//#include <uuids.h> +#include <dshow.h> +#ifndef AM_DBG +#define AM_DBG if(0) +#endif + +#include <process.h> + +using namespace ambulantX; + +//using ambulant::lib::win32::win_report_error; +//using ambulant::lib::win32::win_trace_error; +//using ambulant::lib::logger; + +#ifdef WITH_TPB_AUDIO_SPEEDUP +bool speedup_filter_available; +bool speedup_filter_available_valid; +#endif + +#define win_report_error +#define win_trace_error +#define debugX +#define errorX +#define traceX + + +unsigned __stdcall eventHandler(void* lpParam) { +//static DWORD WINAPI eventHandler(LPVOID lpParam) { + long lEventCode, lParam1, lParam2; + HRESULT hResult = E_FAIL; + bool bSelfBreak = false; + + gui::dx::audio_playerX *pPlayer = (gui::dx::audio_playerX*)lpParam; + + while(!bSelfBreak) { + hResult = E_FAIL; + hResult = pPlayer->m_media_event->GetEvent(&lEventCode, &lParam1, &lParam2, INFINITE); + pPlayer->m_media_event->FreeEventParams(lEventCode, lParam1, lParam2); + if (hResult == S_OK) { + switch(lEventCode) { + case EC_COMPLETE: + pPlayer->stop(false, true); + pPlayer->sendMessageCallback(); + bSelfBreak = true; + break; + case EC_USER + 4: + //pPlayer->stop(false, true); + pPlayer->sendMessageCallback(); + bSelfBreak = true; + break; + } + } + } + _endthreadex( 0 ); + return 0; +} + + +gui::dx::audio_playerX::audio_playerX() +: +//m_url(url), +m_graph_builder(0), +m_media_control(0), +m_media_position(0), +m_media_event(0), +#ifdef WITH_TPB_AUDIO_SPEEDUP +m_audio_speedup(0), +#endif +m_basic_audio(0), +hEventHandler(0) +{ + set_rate(1.7); + InitializeCriticalSection(&m_csSequence); +} + +gui::dx::audio_playerX::~audio_playerX() +{ + stop(false); + DeleteCriticalSection(&m_csSequence); +} + +gui::dx::audio_playerX* gui::dx::audio_playerX::pinstance = 0; + +gui::dx::audio_playerX* gui::dx::audio_playerX::Instance() +{ + if (pinstance == 0) // is it the first call? + { + pinstance = new gui::dx::audio_playerX(); // create sole instance + } + return pinstance; // address of sole instance +} +void gui::dx::audio_playerX::DestroyInstance() +{ + if (pinstance) delete pinstance; +} + + +void gui::dx::audio_playerX::start(double t) { + if(is_playing()) pause(); + seek(t); + resume(); +} + +void gui::dx::audio_playerX::end_thread() { + if (hEventHandler==NULL) return; + + IMediaEventSink *pIMES = NULL; + m_graph_builder->QueryInterface(IID_IMediaEventSink, (void**) &pIMES); + pIMES->Notify(EC_USER + 4, 0, 0); + pIMES->Release(); + pIMES = NULL; + + DWORD hr = WaitForSingleObject(hEventHandler, 1000); + switch (hr) { + case WAIT_FAILED: { + int i = 0; + break; + } + + case WAIT_ABANDONED + : { + int i = 0; + break;} + + case WAIT_OBJECT_0 + : { + int i = 0; + break;} + + case WAIT_TIMEOUT: { + int i = 0; + break;} + + } + hEventHandler = NULL; +} + +void gui::dx::audio_playerX::release_player() { + + if(m_graph_builder) { + + if(m_media_event) { + m_media_event->Release(); + m_media_event = 0; + } + if(m_media_position) { + m_media_position->Release(); + m_media_position = 0; + } + if(m_media_control) { + m_media_control->Release(); + m_media_control = 0; + } + if(m_basic_audio) { + m_basic_audio->Release(); + m_basic_audio = 0; + } +#ifdef WITH_TPB_AUDIO_SPEEDUP + if(m_audio_speedup) { + m_audio_speedup->Release(); + m_audio_speedup = 0; + } +#endif + m_graph_builder->Release(); + m_graph_builder = 0; + } +} + +void gui::dx::audio_playerX::stop(bool fromPlay, bool fromThread) { + + + { + if (!fromPlay) { + EnterCriticalSection(&m_csSequence); + } + if(m_media_control == 0) { + LeaveCriticalSection(&m_csSequence); + return; + } + + if (!fromThread) { + end_thread(); + } else { + hEventHandler = NULL; + } + + if (!fromThread) { + HRESULT hr = m_media_control->Stop(); + if(FAILED(hr)) { + win_report_error("IMediaControl::stop()", hr); + } + + if (m_media_control->StopWhenReady() != S_OK) { + long state, i; + + for (i = 0; i < 100; i++) { + m_media_control->GetState(10, &state); + if (state == State_Stopped) break; + } + + if (i == 100) { + int debug = 0; + } + } + } + release_player(); + if (!fromPlay) { + LeaveCriticalSection(&m_csSequence); + } + } +} + +void gui::dx::audio_playerX::pause(void) { + if(m_media_control == 0) return; + HRESULT hr = m_media_control->Pause(); + if(FAILED(hr)) { + win_report_error("IMediaControl::pause()", hr); + } +} + +void gui::dx::audio_playerX::resume() { + if(m_media_control == 0) { + debugX("Invalid call to audio_playerX::run"); + return; + } + HRESULT hr = m_media_control->Run(); + if(FAILED(hr)) { + win_report_error("IMediaControl::run()", hr); + } +} + +void gui::dx::audio_playerX::seek(double t) { + if(m_media_position == 0) return; + HRESULT hr = m_media_position->put_CurrentPosition(REFTIME(t)); + if(FAILED(hr)) + win_report_error("IMediaPosition::put_CurrentPosition()", hr); +} + +void gui::dx::audio_playerX::endseek(double t) { + if(m_media_position == 0) return; + HRESULT hr = m_media_position->put_StopTime(REFTIME(t)); + if(FAILED(hr)) + win_report_error("IMediaPosition::put_StopTime()", hr); +} + +std::pair<bool, double> gui::dx::audio_playerX::get_dur() { + if(m_media_position == 0) { + debugX("Invalid call to audio_playerX::get_duration"); + return std::pair<bool, double>(false, 0); + } + REFTIME dur = 0.0; + HRESULT hr = m_media_position->get_Duration(&dur); + if(FAILED(hr)) { + win_report_error("IMediaPosition::get_Duration()", hr); + return std::pair<bool, double>(false, 0); + } + return std::pair<bool, double>(dur>0, dur); +} + +bool gui::dx::audio_playerX::can_play() { + return m_graph_builder && + m_media_event && + m_media_position && + m_media_control && + m_media_event; +} + +bool gui::dx::audio_playerX::is_playing() { + + EnterCriticalSection(&m_csSequence); + + if(m_media_control == 0) { + LeaveCriticalSection(&m_csSequence);return false;} + + long msTimeout = 0; + long state; + m_media_control->GetState(msTimeout, &state); + + LeaveCriticalSection(&m_csSequence); + + return (state == State_Running); + + /* + + if(m_media_event == 0) { + LeaveCriticalSection(&m_csSequence);return false;} + + long evCode = 0; + HRESULT hr = m_media_event->WaitForCompletion(msTimeout, &evCode); + if(hr == E_ABORT) return true; + else if(hr == S_OK) return false; + else if(FAILED(hr)) { + // XXXJack: this error occurs all the time... + if (hr == 0x80040227) return false; + win_trace_error("IMediaEvent::WaitForCompletion()", hr); + return false; + } + + LeaveCriticalSection(&m_csSequence); + return evCode == 0; + */ +} + +#if 0 +double gui::dx::audio_playerX::get_position() { + if(m_media_position == 0) { + debugX("Invalid call to audio_playerX::get_current_position"); + return 0.0; + } + REFTIME pos = 0.0; + HRESULT hr = m_media_position->get_CurrentPosition(&pos); + if(FAILED(hr)) { + win_report_error("IMediaPosition::get_CurrentPosition()", hr); + return 0.0; + } + return pos; +} +#endif + + +#ifdef WITH_TPB_AUDIO_SPEEDUP +void gui::dx::audio_playerX::initialize_speedup_filter() { + if (speedup_filter_available_valid && !speedup_filter_available) { + // We don't seem to have the filter. Too bad. + return; + } + // Either the filter exists or we haven't tried yet. Let's try to create + // it and remember whether it worked. + IBaseFilter *pNewFilter = NULL; + + + +#ifdef _DEBUG + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (hr == S_FALSE) CoUninitialize(); + _ASSERT(hr == S_FALSE); +#endif + HRESULT res; + res = CoCreateInstance(CLSID_TPBVupp69, NULL, CLSCTX_INPROC_SERVER, + IID_IBaseFilter, (void**)&pNewFilter); + + if (res != S_OK) { + traceX("dx_audio_player: Speedup filter not available, error 0x%x", res); + speedup_filter_available = false; + speedup_filter_available_valid = true; + return; + } + res = m_graph_builder->AddFilter(pNewFilter, NULL); + if (res != S_OK) { + traceX("dx_audio_player: AddFilter(Speedup filter): error 0x%x", res); + pNewFilter->Release(); + return; + } + speedup_filter_available = true; + speedup_filter_available_valid = true; + // AM_DBG lib::debugX("dx_audio_player: added speedup filter to graph"); + + // Next step: find out where we want to add the filter to the graph. + // We iterate over the filter graph, then for each item in the graph + // we iterate over the connected output pins util we find one we like. + IPin *pOutputPin = NULL; + IPin *pInputPin = NULL; + IEnumFilters *pEnumFilters = NULL; + res = m_graph_builder->EnumFilters(&pEnumFilters); + if (res != S_OK) { + traceX("dx_audio_filter: EnumFilters: error 0x%x", res); + return; + } + + IBaseFilter *pCurFilter; + while (pOutputPin == NULL && (res=pEnumFilters->Next(1, &pCurFilter, NULL)) == S_OK) { + AM_DBG { + FILTER_INFO info; + LPWSTR vendorInfo; + res = pCurFilter->QueryFilterInfo(&info); + if (res != S_OK) info.achName[0] = 0; + res = pCurFilter->QueryVendorInfo(&vendorInfo); + if (res != S_OK) vendorInfo = L""; + //ambulant::lib::textptr tInfo(info.achName); + //ambulant::lib::textptr tVendorInfo(vendorInfo); + //lib::debugX("dx_audio_filter: filter found: '%s' vendor '%s'", tInfo.c_str(), tVendorInfo.c_str()); + } + IEnumPins *pEnumPins; + res = pCurFilter->EnumPins(&pEnumPins); + IPin *pCurPin; + while (pOutputPin == NULL && (res=pEnumPins->Next(1, &pCurPin, NULL)) == S_OK) { + AM_MEDIA_TYPE mediaType; + PIN_DIRECTION curPinDir; + res = pCurPin->QueryDirection(&curPinDir); + HRESULT res2 = pCurPin->ConnectionMediaType(&mediaType); + if (res == S_OK && + res2 == S_OK && + curPinDir == PINDIR_OUTPUT && + mediaType.majortype == MEDIATYPE_Audio&& + mediaType.subtype == MEDIASUBTYPE_PCM){ + pOutputPin = pCurPin; + res = pOutputPin->ConnectedTo(&pInputPin); + if (res != S_OK) { + // This output pin was the correct type, but not connected. + // So it cannot be the one we're looking for. + pOutputPin = pInputPin = NULL; + } else { + // Found it! + pOutputPin->AddRef(); + pInputPin->AddRef(); + } + } + if (res2 == S_OK) { + if (mediaType.cbFormat != 0) { + CoTaskMemFree((PVOID)mediaType.pbFormat); + } + } + pCurPin->Release(); + } + if (res != S_FALSE && res != S_OK) + traceX("dx_audio_filter: enumerating pins: error 0x%x", res); + pEnumPins->Release(); + pCurFilter->Release(); + } + if (res != S_... [truncated message content] |