diff --git a/docs/LittlePiggyTrackerConf.md b/docs/LittlePiggyTrackerConf.md index 35f22f97..a16c2600 100644 --- a/docs/LittlePiggyTrackerConf.md +++ b/docs/LittlePiggyTrackerConf.md @@ -282,7 +282,8 @@ They are currenly _mostly_ used for **W32** but might extend in the future to ot - `AUDIODRIVER`: Allows to specify which driver to open. It takes the first drvier whose name matches the beginning of the string. For example, to force using a realtek soundcard instead of the default one, you can just specify “Real” - `AUDIOBUFFERSIZE`: Allows to tweak the default buffersize used for the audio. If the piggy glitches, increase this value. - `AUDIOPREBUFFERCOUNT`: Even if the computer has the ability to run the piggy full screen, some sound hardware needs nearly instant reply for the couple of first buffers. If you have upped the `AUDIOBUFFERSIZE` but still get glitches, try putting it back to something decent (like 512) and define `AUDIOPREBUFFERCOUNT` to be 2,3,… that way, a set of blank buffer will be queued, ready for the soundcard to grab, before the sequencer is actually kicked in. - +- `AUDIOSAMPLERATE`: SDL2 Only, Modern Linux systems running pipewire often run at 48000 rather then 44100. This setting +allows you to run at the system default. SDL may use a different sample rate if the specified one is not supported. Currently 44100 and 48000 have been tested on Linux. ```xml diff --git a/sources/Adapters/LINUX/System/LINUXSystem.cpp b/sources/Adapters/LINUX/System/LINUXSystem.cpp index 39031ff1..85206b3d 100644 --- a/sources/Adapters/LINUX/System/LINUXSystem.cpp +++ b/sources/Adapters/LINUX/System/LINUXSystem.cpp @@ -1,18 +1,18 @@ #include "LINUXSystem.h" -#include -#include -#include -#include #include "Adapters/SDL2/GUI/GUIFactory.h" #include "Adapters/SDL2/GUI/SDLEventManager.h" #include "Adapters/SDL2/GUI/SDLGUIWindowImp.h" #include "Adapters/SDL2/Timer/SDLTimer.h" #include "Adapters/Unix/FileSystem/UnixFileSystem.h" #include "Adapters/Unix/Process/UnixProcess.h" -#include "Application/Controllers/ControlRoom.h" #include "Application/Commands/NodeList.h" +#include "Application/Controllers/ControlRoom.h" #include "Application/Model/Config.h" #include "System/Console/Logger.h" +#include +#include +#include +#include #ifdef DUMMYMIDI #include "Adapters/Dummy/Midi/DummyMidi.h" @@ -46,97 +46,95 @@ static int secbase = 0; * starts the main loop */ int LINUXSystem::MainLoop() { - eventManager_->InstallMappings(); - return eventManager_->MainLoop() ; + eventManager_->InstallMappings(); + return eventManager_->MainLoop(); }; /* * initializes the application */ -void LINUXSystem::Boot(int argc,char **argv) { +void LINUXSystem::Boot(int argc, char **argv) { - SDL_setenv((char *)"SDL_VIDEO_X11_WMCLASS",(char *)"LittleGPTracker",1) ; + SDL_setenv((char *)"SDL_VIDEO_X11_WMCLASS", (char *)"LittleGPTracker", 1); - // Install System - System::Install(new LINUXSystem()); + // Install System + System::Install(new LINUXSystem()); - // Install FileSystem - FileSystem::Install(new UnixFileSystem()); + // Install FileSystem + FileSystem::Install(new UnixFileSystem()); - // Install aliases - char buff[1024]; - ssize_t len = ::readlink("/proc/self/exe",buff,sizeof(buff)-1); - if (len != -1) - { - buff[len] = 0; - } - else - { - strcpy(buff,"."); - } - Path::SetAlias("bin",dirname(buff)) ; - Path::SetAlias("root",".") ; + // Install aliases + char buff[1024]; + ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff) - 1); + if (len != -1) { + buff[len] = 0; + } else { + strcpy(buff, "."); + } + Path::SetAlias("bin", dirname(buff)); + Path::SetAlias("root", "."); - // always use stdout, user can capture in launch script - Trace::GetInstance()->SetLogger(*(new StdOutLogger())); + // always use stdout, user can capture in launch script + Trace::GetInstance()->SetLogger(*(new StdOutLogger())); - // Process arguments - Config::GetInstance()->ProcessArguments(argc,argv) ; + // Process arguments + Config::GetInstance()->ProcessArguments(argc, argv); - // Install GUI Factory - I_GUIWindowFactory::Install(new GUIFactory()) ; + // Install GUI Factory + I_GUIWindowFactory::Install(new GUIFactory()); - // Install Timers - TimerService::GetInstance()->Install(new SDLTimerService()) ; + // Install Timers + TimerService::GetInstance()->Install(new SDLTimerService()); #ifdef JACKAUDIO - Trace::Log("System","Installing JACK audio") ; - Audio::Install(new JackAudio(AudioSettings hints)); + Trace::Log("System", "Installing JACK audio"); + Audio::Install(new JackAudio(AudioSettings hints)); #endif #ifdef RTAUDIO - Trace::Log("System","Installing RT audio") ; - AudioSettings hints ; - hints.bufferSize_= 256 ; - hints.preBufferCount_=2 ; - Audio::Install(new RTAudioStub(hints)) ; + Trace::Log("System", "Installing RT audio"); + AudioSettings hints; + hints.bufferSize_ = 256; + hints.preBufferCount_ = 2; + Audio::Install(new RTAudioStub(hints)); #endif #ifdef SDLAUDIO - Trace::Log("System","Installing SDL audio") ; - AudioSettings hint; - hint.bufferSize_ = 1024; - hint.preBufferCount_ = 8; - Audio::Install(new SDLAudio(hint)); + Trace::Log("System", "Installing SDL audio"); + AudioSettings hint; + hint.bufferSize_ = 1024; + hint.preBufferCount_ = 8; + hint.sampleRate_ = 44100; + Audio::Install(new SDLAudio(hint)); #endif #ifdef DUMMYMIDI - Trace::Log("System","Installing DUMMY MIDI") ; - MidiService::Install(new DummyMidi()); + Trace::Log("System", "Installing DUMMY MIDI"); + MidiService::Install(new DummyMidi()); #endif #ifdef JACKMIDI - Trace::Log("System","Installing JACK MIDI") ; - MidiService::Install(new JackMidiService()) ; + Trace::Log("System", "Installing JACK MIDI"); + MidiService::Install(new JackMidiService()); #endif #ifdef RTMIDI - Trace::Log("System","Installing RT MIDI") ; - MidiService::Install(new RTMidiService()) ; + Trace::Log("System", "Installing RT MIDI"); + MidiService::Install(new RTMidiService()); #endif - // Install Threads - SysProcessFactory::Install(new UnixProcessFactory()); + // Install Threads + SysProcessFactory::Install(new UnixProcessFactory()); - if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0 ) { - return; - } - SDL_ShowCursor(SDL_DISABLE); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { + return; + } + SDL_ShowCursor(SDL_DISABLE); - atexit(SDL_Quit); + atexit(SDL_Quit); - eventManager_ = I_GUIWindowFactory::GetInstance()->GetEventManager(); - eventManager_ -> Init(); + eventManager_ = I_GUIWindowFactory::GetInstance()->GetEventManager(); + eventManager_->Init(); }; void LINUXSystem::Shutdown() {}; @@ -145,62 +143,60 @@ void LINUXSystem::Shutdown() {}; * get current time for status display */ unsigned long LINUXSystem::GetClock() { - struct timeval tp; - - gettimeofday(&tp, NULL); - if (!secbase) { - secbase = tp.tv_sec; - return long(tp.tv_usec/1000.0); - } - return long((tp.tv_sec - secbase)*1000 + tp.tv_usec/1000.0); + struct timeval tp; + + gettimeofday(&tp, NULL); + if (!secbase) { + secbase = tp.tv_sec; + return long(tp.tv_usec / 1000.0); + } + return long((tp.tv_sec - secbase) * 1000 + tp.tv_usec / 1000.0); } /* * wraps sleep, guess we never sleep! */ void LINUXSystem::Sleep(int millisec) { - //if (millisec>0) - //::Sleep(millisec) ; + // if (millisec>0) + //::Sleep(millisec) ; } /* * wraps malloc */ void *LINUXSystem::Malloc(unsigned size) { - void *ptr=malloc(size) ; - //Trace::Debug("alloc:%x (%d)",ptr,size) ; - return ptr ; + void *ptr = malloc(size); + // Trace::Debug("alloc:%x (%d)",ptr,size) ; + return ptr; } /* * wraps free */ -void LINUXSystem::Free(void *ptr) { - free(ptr); -} +void LINUXSystem::Free(void *ptr) { free(ptr); } /* * wraps memset */ -void LINUXSystem::Memset(void *addr,char val,int size) { +void LINUXSystem::Memset(void *addr, char val, int size) { #ifdef _64BIT unsigned int ad = (intptr_t)addr; #else - unsigned int ad=(unsigned int)addr; + unsigned int ad = (unsigned int)addr; #endif - if (((ad&0x3)==0)&&((size&0x3)==0)) { // Are we 4-byte aligned ? - unsigned int intVal=0; - for (int i=0;i<4;i++) { - intVal=(intVal<<8)+val; + if (((ad & 0x3) == 0) && ((size & 0x3) == 0)) { // Are we 4-byte aligned ? + unsigned int intVal = 0; + for (int i = 0; i < 4; i++) { + intVal = (intVal << 8) + val; } - unsigned int *dst=(unsigned int *)addr; - size_t intSize=size>>2 ; + unsigned int *dst = (unsigned int *)addr; + size_t intSize = size >> 2; - for (unsigned int i=0;iPostQuitMessage() ; -}; + SDLEventManager::GetInstance()->PostQuitMessage(); +}; /* * get memory usage, guess it's infinite diff --git a/sources/Adapters/SDL2/Audio/SDLAudio.cpp b/sources/Adapters/SDL2/Audio/SDLAudio.cpp index 79d92088..e28253e7 100644 --- a/sources/Adapters/SDL2/Audio/SDLAudio.cpp +++ b/sources/Adapters/SDL2/Audio/SDLAudio.cpp @@ -3,37 +3,43 @@ #include "SDLAudioDriver.h" #include "Services/Audio/AudioOutDriver.h" -SDLAudio::SDLAudio(AudioSettings &hints):Audio(hints) { - hints_=hints; +SDLAudio::SDLAudio(AudioSettings &hints) : Audio(hints) { + hints_ = hints; + drv_ = NULL; } -SDLAudio::~SDLAudio() { -} +SDLAudio::~SDLAudio() {} void SDLAudio::Init() { - AudioSettings settings ; - settings.audioAPI_=GetAudioAPI(); - - settings.bufferSize_=GetAudioBufferSize() ; - settings.preBufferCount_=GetAudioPreBufferCount() ; + AudioSettings settings; + settings.audioAPI_ = GetAudioAPI(); + settings.bufferSize_ = GetAudioBufferSize(); + settings.preBufferCount_ = GetAudioPreBufferCount(); + settings.sampleRate_ = GetPreferredSampleRate(); - SDLAudioDriver *drv=new SDLAudioDriver(settings) ; - AudioOut *out=new AudioOutDriver(*drv) ; - Insert(out) ; -} ; + drv_ = new SDLAudioDriver(settings); + AudioOut *out = new AudioOutDriver(*drv_); + Insert(out); +}; void SDLAudio::Close() { - IteratorPtrit(GetIterator()) ; - for (it->Begin();!it->IsDone();it->Next()) { - AudioOut ¤t=it->CurrentItem() ; - current.Close() ; - } -} ; - -int SDLAudio::GetMixerVolume() { - return 100 ; -} ; - -void SDLAudio::SetMixerVolume(int volume) { -} ; + IteratorPtr it(GetIterator()); + for (it->Begin(); !it->IsDone(); it->Next()) { + AudioOut ¤t = it->CurrentItem(); + current.Close(); + } +}; + +int SDLAudio::GetSampleRate() { + if (!drv_) { + Trace::Error( + "AUDIO", + "Sample rate requested before audio driver is initialised!"); + } + return drv_->GetSampleRate(); +}; + +int SDLAudio::GetMixerVolume() { return 100; }; + +void SDLAudio::SetMixerVolume(int volume) {}; diff --git a/sources/Adapters/SDL2/Audio/SDLAudio.h b/sources/Adapters/SDL2/Audio/SDLAudio.h index b178b848..351e9e01 100644 --- a/sources/Adapters/SDL2/Audio/SDLAudio.h +++ b/sources/Adapters/SDL2/Audio/SDLAudio.h @@ -3,15 +3,21 @@ #include "Services/Audio/Audio.h" -class SDLAudio: public Audio { -public: - SDLAudio(AudioSettings &hints) ; // Allow for different default size for different platform - ~SDLAudio() ; - virtual void Init() ; - virtual void Close() ; - virtual int GetMixerVolume() ; - virtual void SetMixerVolume(int volume) ; -private: - AudioSettings hints_ ; +class SDLAudioDriver; + +class SDLAudio : public Audio { + public: + SDLAudio(AudioSettings &hints); // Allow for different default size for + // different platform + ~SDLAudio(); + virtual void Init(); + virtual void Close(); + int GetSampleRate(); + virtual int GetMixerVolume(); + virtual void SetMixerVolume(int volume); + + private: + AudioSettings hints_; + SDLAudioDriver *drv_; }; #endif diff --git a/sources/Adapters/SDL2/Audio/SDLAudioDriver.cpp b/sources/Adapters/SDL2/Audio/SDLAudioDriver.cpp index 5ec3002e..7d3c2552 100644 --- a/sources/Adapters/SDL2/Audio/SDLAudioDriver.cpp +++ b/sources/Adapters/SDL2/Audio/SDLAudioDriver.cpp @@ -11,7 +11,7 @@ void sdl_callback(void *userdata, Uint8 *stream, int len) { SDLAudioDriverThread::SDLAudioDriverThread(SDLAudioDriver *driver) { // Uncap the semaphore to prevent dropped requests during long OS stalls. - semaphore_=SysSemaphore::Create(0,1024); + semaphore_ = SysSemaphore::Create(0, 1024); driver_ = driver; }; @@ -56,15 +56,15 @@ struct SDL_AudioSpec returned; bool SDLAudioDriver::InitDriver() { // set sound - input.freq = 44100; + input.freq = settings_.sampleRate_; input.format = AUDIO_S16SYS; input.channels = 2; input.callback = sdl_callback; input.samples = settings_.bufferSize_; input.userdata = this; - SDL_SetHint("APP_NAME", "LittleGPTracker"); - SDL_SetHint("AUDIO_DEVICE_APP_NAME", "LittleGPTracker"); + SDL_SetHint("SDL_APP_NAME", "LittleGPTracker"); + SDL_SetHint("SDL_AUDIO_DEVICE_APP_NAME", "LittleGPTracker"); // On my machine this wasn't working. // SDL_AudioDeviceID deviceId = @@ -72,12 +72,13 @@ bool SDLAudioDriver::InitDriver() { // meaning an error or success. int ret = SDL_OpenAudio(&input, &returned); if (ret != 0) { - Trace::Error("Couldn't open sdl audio: %s\n", SDL_GetError()); + Trace::Error("AUDIO", "Couldn't open sdl audio: %s", SDL_GetError()); return false; } const char *driverName = SDL_GetCurrentAudioDriver(); fragSize_ = returned.size; + sampleRate_ = returned.freq; // Allocates a rotating sound buffer unalignedMain_ = (char *)SYS_MALLOC(fragSize_ + SOUND_BUFFER_MAX); // Make sure the buffer is aligned @@ -166,8 +167,9 @@ void SDLAudioDriver::OnChunkDone(Uint8 *stream, int len) { // Use fragSize_ instead of len! miniBlank_ is only allocated to // fragSize_. Using len causes a buffer over-read if SDL requests a // larger chunk. - SYS_MEMCPY(mainBuffer_+bufferSize_-bufferPos_, miniBlank_, fragSize_); - bufferSize_=bufferSize_-bufferPos_+fragSize_ ; + SYS_MEMCPY(mainBuffer_ + bufferSize_ - bufferPos_, miniBlank_, + fragSize_); + bufferSize_ = bufferSize_ - bufferPos_ + fragSize_; bufferPos_ = 0; } else { @@ -184,26 +186,37 @@ void SDLAudioDriver::OnChunkDone(Uint8 *stream, int len) { SYS_FREE(pool_[poolPlayPosition_].buffer_); pool_[poolPlayPosition_].buffer_ = 0; - poolPlayPosition_ = (poolPlayPosition_ + 1) % SOUND_BUFFER_COUNT; - if (thread_) - thread_->Notify(); - // Tick the engine and flush MIDI ONLY when a real logical block is - // processed! This keeps the sequencer perfectly in sync with the - // audio pool consumption, and prevents runaway MIDI generation on - // underruns which fills the ALSA buffer and freezes the thread. - onAudioBufferTick(); - MidiService::GetInstance()->Flush() ; + } + // Tick the engine and flush MIDI for every logical audio block + // processed. This ensures consistent timing for application logic and + // MIDI output, even during underruns where silence is played. + onAudioBufferTick(); + MidiService::GetInstance()->Flush(); + + // Advance poolPlayPosition_ and notify the thread after consuming + // a logical chunk, regardless of whether it was real data or silence. + poolPlayPosition_ = (poolPlayPosition_ + 1) % SOUND_BUFFER_COUNT; + if (thread_) { + thread_->Notify(); } } // Now dump audio to the device SYS_MEMCPY(stream, (short *)(mainBuffer_ + bufferPos_), len); - onAudioBufferTick(); bufferPos_ += len; } int SDLAudioDriver::GetPlayedBufferPercentage() { // return - //100-(bufferSize_-bufferPos_-fragSize_)*100/(bufferSize_-fragSize_) ; + // 100-(bufferSize_-bufferPos_-fragSize_)*100/(bufferSize_-fragSize_) ; return 0; }; + +int SDLAudioDriver::GetSampleRate() { + if (sampleRate_ == 0) { + Trace::Error( + "AUDIO", + "Sample rate requested before audio driver is initialised!"); + } + return sampleRate_; +}; diff --git a/sources/Adapters/SDL2/Audio/SDLAudioDriver.h b/sources/Adapters/SDL2/Audio/SDLAudioDriver.h index 6df6d530..4fd1f3be 100644 --- a/sources/Adapters/SDL2/Audio/SDLAudioDriver.h +++ b/sources/Adapters/SDL2/Audio/SDLAudioDriver.h @@ -2,50 +2,51 @@ #define _SDL_SOUND_H_ #include "Services/Audio/AudioDriver.h" -#include #include "System/Process/Process.h" +#include + +class SDLAudioDriver; + +class SDLAudioDriverThread : public SysThread { + public: + SDLAudioDriverThread(SDLAudioDriver *driver); + virtual ~SDLAudioDriverThread() {}; + virtual bool Execute(); + virtual void RequestTermination(); + void Notify(); + + private: + SDLAudioDriver *driver_; + SysSemaphore *semaphore_; +}; + +class SDLAudioDriver : public AudioDriver { + public: + SDLAudioDriver(AudioSettings &settings); + virtual ~SDLAudioDriver(); -class SDLAudioDriver ; - -class SDLAudioDriverThread: public SysThread { -public: - SDLAudioDriverThread(SDLAudioDriver *driver) ; - virtual ~SDLAudioDriverThread() {} ; - virtual bool Execute() ; - virtual void RequestTermination() ; - void Notify() ; -private: - SDLAudioDriver *driver_ ; - SysSemaphore *semaphore_ ; -} ; - -class SDLAudioDriver:public AudioDriver { -public: - SDLAudioDriver(AudioSettings &settings) ; - virtual ~SDLAudioDriver() ; - - // Sound implementation - virtual bool InitDriver() ; - virtual void CloseDriver(); - virtual bool StartDriver() ; - virtual void StopDriver(); - virtual int GetPlayedBufferPercentage() ; - virtual int GetSampleRate() { return 44100 ; } ; - virtual bool Interlaced() { return true ; } ; - virtual double GetStreamTime() ; - // Additional - void OnChunkDone(Uint8 *stream,int len) ; - -private: - int fragSize_ ; // Actual fragsize used by the driver - char *unalignedMain_ ; - char *mainBuffer_ ; - char *miniBlank_ ; - int bufferPos_ ; - int bufferSize_ ; - SDLAudioDriverThread *thread_ ; - Uint32 startTime_ ; -} ; + // Sound implementation + virtual bool InitDriver(); + virtual void CloseDriver(); + virtual bool StartDriver(); + virtual void StopDriver(); + virtual int GetPlayedBufferPercentage(); + virtual int GetSampleRate(); + virtual bool Interlaced() { return true; }; + virtual double GetStreamTime(); + // Additional + void OnChunkDone(Uint8 *stream, int len); + private: + int fragSize_; // Actual fragsize used by the driver + char *unalignedMain_; + char *mainBuffer_; + char *miniBlank_; + int bufferPos_; + int bufferSize_; + int sampleRate_; + SDLAudioDriverThread *thread_; + Uint32 startTime_; +}; #endif diff --git a/sources/Application/FX/FxPrinter.cpp b/sources/Application/FX/FxPrinter.cpp index 7bc19f6c..20b9e0d2 100644 --- a/sources/Application/FX/FxPrinter.cpp +++ b/sources/Application/FX/FxPrinter.cpp @@ -1,18 +1,20 @@ #include "FxPrinter.h" +#include "Services/Audio/Audio.h" -FxPrinter::FxPrinter(ViewData* viewData) - : samples_dir("project:samples"), - impulse_dir("root:samplelib"), +FxPrinter::FxPrinter(ViewData *viewData) + : samples_dir("project:samples"), impulse_dir("root:samplelib"), viewData_(viewData) { int curInstr = viewData_->currentInstrument_; - InstrumentBank* bank = viewData_->project_->GetInstrumentBank(); - instrument_ = static_cast(bank->GetInstrument(curInstr)); + InstrumentBank *bank = viewData_->project_->GetInstrumentBank(); + instrument_ = + static_cast(bank->GetInstrument(curInstr)); notificationResult_ = ""; // Assume ffmpeg exists but swap for local ffmpig if it doesn't ffmpeg_ = "ffmpeg"; Path pigPath("bin:ffmpig"); Path ffmpigPath(pigPath.GetPath().c_str()); - if(ffmpigPath.Exists()) ffmpeg_ = pigPath.GetPath(); + if (ffmpigPath.Exists()) + ffmpeg_ = pigPath.GetPath(); } void FxPrinter::setParams() { @@ -33,7 +35,8 @@ void FxPrinter::setPaths() { std::string FxPrinter::parseCommand() { std::string command; float padDur = static_cast(irPad_) / 1000; - float smplLength = static_cast(instrument_->GetSampleSize()) / 44100; + float smplLength = static_cast(instrument_->GetSampleSize()) / + Audio::GetInstance()->GetSampleRate(); std::ostringstream cm1, cm2, cm3, cm4, cm5; cm1 << ffmpeg_ << " -y -i " diff --git a/sources/Application/Instruments/WavFileWriter.cpp b/sources/Application/Instruments/WavFileWriter.cpp index 8caa1042..0a3e30dd 100644 --- a/sources/Application/Instruments/WavFileWriter.cpp +++ b/sources/Application/Instruments/WavFileWriter.cpp @@ -1,117 +1,115 @@ #include "WavFileWriter.h" +#include "Services/Audio/Audio.h" #include "System/Console/Trace.h" -WavFileWriter::WavFileWriter(const char *path): - file_(0), - buffer_(0), - bufferSize_(0), - sampleCount_(0) -{ - Path filePath(path) ; - file_=FileSystem::GetInstance()->Open(filePath.GetPath().c_str(),"wb") ; - if (file_) { +WavFileWriter::WavFileWriter(const char *path) + : file_(0), buffer_(0), bufferSize_(0), sampleCount_(0) { + Path filePath(path); + file_ = FileSystem::GetInstance()->Open(filePath.GetPath().c_str(), "wb"); + if (file_) { - // RIFF chunk + // RIFF chunk - unsigned int chunk ; - chunk=Swap32(0x46464952) ; - file_->Write(&chunk,1,4); - unsigned int size ; - size=0 ; // to be filled later - file_->Write(&size,1,4); + unsigned int chunk; + chunk = Swap32(0x46464952); + file_->Write(&chunk, 1, 4); + unsigned int size; + size = 0; // to be filled later + file_->Write(&size, 1, 4); - // WAVE chunk + // WAVE chunk - chunk=Swap32(0x45564157) ; - file_->Write(&chunk,1,4); - chunk=Swap32(0x20746D66) ; - file_->Write(&chunk,1,4); - size=Swap32(16) ; - file_->Write(&size,1,4); + chunk = Swap32(0x45564157); + file_->Write(&chunk, 1, 4); + chunk = Swap32(0x20746D66); + file_->Write(&chunk, 1, 4); + size = Swap32(16); + file_->Write(&size, 1, 4); - unsigned short ushort ; - ushort=Swap16(1) ; // compression - file_->Write(&ushort,1,2); - ushort=Swap16(2) ; // nChannels - file_->Write(&ushort,1,2); - unsigned int sampleRate=Swap32(44100) ; - file_->Write(&sampleRate,1,4); + unsigned short ushort; + ushort = Swap16(1); // compression + file_->Write(&ushort, 1, 2); + ushort = Swap16(2); // nChannels + file_->Write(&ushort, 1, 2); + unsigned int sampleRate = Swap32(Audio::GetInstance()->GetSampleRate()); + file_->Write(&sampleRate, 1, 4); - unsigned int byteRate=Swap32(4*44100) ; - file_->Write(&byteRate,1,4); + unsigned int byteRate = + Swap32(4 * Audio::GetInstance()->GetSampleRate()); + file_->Write(&byteRate, 1, 4); - ushort=Swap16(4) ; // blockalign - file_->Write(&ushort,1,2); + ushort = Swap16(4); // blockalign + file_->Write(&ushort, 1, 2); - ushort=Swap16(16) ; // bitPerSample - file_->Write(&ushort,1,2); + ushort = Swap16(16); // bitPerSample + file_->Write(&ushort, 1, 2); - // data subchunk + // data subchunk - chunk = Swap32(0x61746164); - file_->Write(&chunk,1,4); + chunk = Swap32(0x61746164); + file_->Write(&chunk, 1, 4); - size=0 ; // to be updated later - file_->Write(&chunk,1,4); - } ; -} ; + size = 0; // to be updated later + file_->Write(&chunk, 1, 4); + }; +}; -WavFileWriter::~WavFileWriter() { - Close(); -} +WavFileWriter::~WavFileWriter() { Close(); } -void WavFileWriter::AddBuffer(fixed *bufferIn,int size) { +void WavFileWriter::AddBuffer(fixed *bufferIn, int size) { - if (!file_) return ; + if (!file_) + return; - // allocate a short buffer for transfer + // allocate a short buffer for transfer - if (size>bufferSize_) { - SAFE_FREE(buffer_) ; - buffer_=(short *)malloc(size*2*sizeof(short)) ; - bufferSize_=size ; - } ; + if (size > bufferSize_) { + SAFE_FREE(buffer_); + buffer_ = (short *)malloc(size * 2 * sizeof(short)); + bufferSize_ = size; + }; - if (!buffer_) return ; + if (!buffer_) + return; - short *s=buffer_ ; - fixed *p=bufferIn ; + short *s = buffer_; + fixed *p = bufferIn; - fixed v; - fixed f_32767=i2fp(32767) ; - fixed f_m32768=i2fp(-32768) ; + fixed v; + fixed f_32767 = i2fp(32767); + fixed f_m32768 = i2fp(-32768); - for (int i=0;if_32767) { - v=f_32767 ; - } else if (vWrite(buffer_,2,size*2) ; - sampleCount_+=size ; -} ; + v = *p++; + if (v > f_32767) { + v = f_32767; + } else if (v < f_m32768) { + v = f_m32768; + } + *s++ = short(fp2i(v)); + }; + file_->Write(buffer_, 2, size * 2); + sampleCount_ += size; +}; void WavFileWriter::Close() { - if (!file_) return ; + if (!file_) + return; - size_t len=file_->Tell() ; - len=Swap32(len-8) ; - file_->Seek(4,SEEK_SET) ; - file_->Write(&len,4,1) ; + size_t len = file_->Tell(); + len = Swap32(len - 8); + file_->Seek(4, SEEK_SET); + file_->Write(&len, 4, 1); - file_->Seek(40,SEEK_SET) ; - sampleCount_=Swap32(sampleCount_*4) ; - file_->Write(&sampleCount_,4,1) ; + file_->Seek(40, SEEK_SET); + sampleCount_ = Swap32(sampleCount_ * 4); + file_->Write(&sampleCount_, 4, 1); - file_->Seek(0,SEEK_END) ; + file_->Seek(0, SEEK_END); - file_->Close() ; - SAFE_DELETE(file_) ; - SAFE_FREE(buffer_) ; - -} ; \ No newline at end of file + file_->Close(); + SAFE_DELETE(file_); + SAFE_FREE(buffer_); +}; diff --git a/sources/Services/Audio/Audio.cpp b/sources/Services/Audio/Audio.cpp index ebe37861..50b940a8 100644 --- a/sources/Services/Audio/Audio.cpp +++ b/sources/Services/Audio/Audio.cpp @@ -1,45 +1,40 @@ #include "Audio.h" #include "Application/Model/Config.h" -Audio::Audio(AudioSettings &hints):T_SimpleList(true),settings_() { - - // Hints contains the basic information about the - // default settings for the platform. All of the can - // be overriden through the config file - - Config *config=Config::GetInstance() ; - const char *v=config->GetValue("AUDIOAPI") ; - settings_.audioAPI_=v?v:hints.audioAPI_ ; - v=config->GetValue("AUDIODEVICE") ; - settings_.audioDevice_=v?v:hints.audioDevice_ ; - v=config->GetValue("AUDIOBUFFERSIZE") ; - settings_.bufferSize_=v?atoi(v):hints.bufferSize_ ; - v=config->GetValue("AUDIOPREBUFFERCOUNT") ; - settings_.preBufferCount_=v?atoi(v):hints.preBufferCount_ ; - - - Trace::Log("AUDIO","Audio object initialised with") ; - Trace::Log("AUDIO","Api:%s",settings_.audioAPI_.c_str()) ; - Trace::Log("AUDIO","Device:%s",settings_.audioDevice_.c_str()) ; - Trace::Log("AUDIO","Buffer size:%d",settings_.bufferSize_) ; - Trace::Log("AUDIO","Pre Buffer Count:%d",settings_.preBufferCount_) ; +Audio::Audio(AudioSettings &hints) : T_SimpleList(true), settings_() { + + // Hints contains the basic information about the + // default settings for the platform. All of the can + // be overriden through the config file + + Config *config = Config::GetInstance(); + const char *v = config->GetValue("AUDIOAPI"); + settings_.audioAPI_ = v ? v : hints.audioAPI_; + v = config->GetValue("AUDIODEVICE"); + settings_.audioDevice_ = v ? v : hints.audioDevice_; + v = config->GetValue("AUDIOBUFFERSIZE"); + settings_.bufferSize_ = v ? atoi(v) : hints.bufferSize_; + v = config->GetValue("AUDIOPREBUFFERCOUNT"); + settings_.preBufferCount_ = v ? atoi(v) : hints.preBufferCount_; + v = config->GetValue("AUDIOSAMPLERATE"); + settings_.sampleRate_ = v ? atoi(v) : hints.sampleRate_; + + Trace::Log("AUDIO", "Audio object initialised with"); + Trace::Log("AUDIO", "Api:%s", settings_.audioAPI_.c_str()); + Trace::Log("AUDIO", "Device:%s", settings_.audioDevice_.c_str()); + Trace::Log("AUDIO", "Buffer size:%d", settings_.bufferSize_); + Trace::Log("AUDIO", "Pre Buffer Count:%d", settings_.preBufferCount_); + Trace::Log("AUDIO", "Preferred Sample Rate:%d", settings_.sampleRate_); } -Audio::~Audio() { -} +Audio::~Audio() {} -const char *Audio::GetAudioAPI() { - return settings_.audioAPI_.c_str() ; -} +const char *Audio::GetAudioAPI() { return settings_.audioAPI_.c_str(); } + +const char *Audio::GetAudioDevice() { return settings_.audioDevice_.c_str(); }; -const char *Audio::GetAudioDevice() { - return settings_.audioDevice_.c_str() ; -} ; +int Audio::GetAudioBufferSize() { return settings_.bufferSize_; }; -int Audio::GetAudioBufferSize() { - return settings_.bufferSize_ ; -} ; +int Audio::GetAudioPreBufferCount() { return settings_.preBufferCount_; }; -int Audio::GetAudioPreBufferCount() { - return settings_.preBufferCount_ ; -} ; +int Audio::GetPreferredSampleRate() { return settings_.sampleRate_; }; diff --git a/sources/Services/Audio/Audio.h b/sources/Services/Audio/Audio.h index bf0666ee..daedc9b9 100644 --- a/sources/Services/Audio/Audio.h +++ b/sources/Services/Audio/Audio.h @@ -2,34 +2,34 @@ #ifndef _AUDIO_H_ #define _AUDIO_H_ -#include "Foundation/T_Factory.h" -#include "Foundation/T_SimpleList.h" #include "AudioOut.h" #include "AudioSettings.h" +#include "Foundation/T_Factory.h" +#include "Foundation/T_SimpleList.h" +class Audio : public T_Factory