From 1165d5e18aa006db62ac40a8d218d7affb5151f7 Mon Sep 17 00:00:00 2001 From: beveloper Date: Sun, 17 Aug 2003 16:03:46 +0000 Subject: [PATCH] added support for a settings file, some fixes in the deferred saving code, added save/load to mixer connections git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4294 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/media-add-ons/mixer/AudioMixer.cpp | 26 +++- .../media/media-add-ons/mixer/AudioMixer.h | 2 +- .../media/media-add-ons/mixer/MixerAddOn.cpp | 8 +- .../media/media-add-ons/mixer/MixerCore.cpp | 20 +-- .../media/media-add-ons/mixer/MixerCore.h | 4 +- .../media-add-ons/mixer/MixerSettings.cpp | 119 ++++++++++++------ .../media/media-add-ons/mixer/MixerSettings.h | 28 +++-- 7 files changed, 137 insertions(+), 70 deletions(-) diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp index c726eed78b..79bb0f5761 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -40,7 +42,7 @@ static void multi_audio_format_specialize(media_multi_audio_format *format, cons #define FORMAT_USER_DATA_MAGIC_1 0xc84173bd #define FORMAT_USER_DATA_MAGIC_2 0x4af62b7d -AudioMixer::AudioMixer(BMediaAddOn *addOn) +AudioMixer::AudioMixer(BMediaAddOn *addOn, bool isSystemMixer) : BMediaNode("Audio Mixer"), BBufferConsumer(B_MEDIA_RAW_AUDIO), BBufferProducer(B_MEDIA_RAW_AUDIO), @@ -67,6 +69,18 @@ AudioMixer::AudioMixer(BMediaAddOn *addOn) fDefaultFormat.u.raw_audio.valid_bits = 0; fDefaultFormat.u.raw_audio.matrix_mask = 0; + if (isSystemMixer) { + // to get persistent settings, assign a settings file + BPath path; + if (B_OK != find_directory (B_USER_SETTINGS_DIRECTORY, &path)) + path.SetTo("/boot/home/config/settings/"); + path.Append("System Audio Mixer"); + fCore->Settings()->SetSettingsFile(path.Path()); + + // disable stop on the auto started (system) mixer + DisableNodeStop(); + } + ApplySettings(); } @@ -328,7 +342,10 @@ AudioMixer::Connected(const media_source &producer, const media_destination &whe sprintf(out_input->name, "Input %ld", out_input->destination.id); // add a new input to the mixer engine - fCore->AddInput(*out_input); + MixerInput *input; + input = fCore->AddInput(*out_input); + + fCore->Settings()->LoadConnectionSettings(input); fCore->Unlock(); @@ -786,6 +803,9 @@ AudioMixer::Connect(status_t error, const media_source &source, const media_dest fCore->EnableOutput(true); fCore->SetTimingInfo(TimeSource(), fDownstreamLatency); fCore->SetOutputBufferGroup(fBufferGroup); + + fCore->Settings()->LoadConnectionSettings(fCore->Output()); + fCore->Unlock(); UpdateParameterWeb(); @@ -1353,6 +1373,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when, goto err; output->SetOutputChannelSourceGain(PARAM_CHAN(id), PARAM_SRC(id), PERCENT_TO_GAIN(static_cast(value)[0])); } + fCore->Settings()->SaveConnectionSettings(output); } else { MixerInput *input; for (int i = 0; (input = fCore->Input(i)); i++) @@ -1457,6 +1478,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when, // but it will change the fokus from tab 3 to tab 1 update = true; } + fCore->Settings()->SaveConnectionSettings(input); } BroadcastNewParameterValue(when, id, const_cast(value), size); err: diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h index 309bece268..ff4ce47885 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h @@ -34,7 +34,7 @@ class AudioMixer : public: - AudioMixer(BMediaAddOn *addOn); + AudioMixer(BMediaAddOn *addOn, bool isSystemMixer); ~AudioMixer(); diff --git a/src/add-ons/media/media-add-ons/mixer/MixerAddOn.cpp b/src/add-ons/media/media-add-ons/mixer/MixerAddOn.cpp index c024c4b503..4d94793187 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerAddOn.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerAddOn.cpp @@ -83,7 +83,7 @@ BMediaNode * AudioMixerAddon::InstantiateNodeFor(const flavor_info* info, BMessage* config, status_t* out_error) { - return new AudioMixer(this); + return new AudioMixer(this, false); } status_t @@ -110,11 +110,7 @@ AudioMixerAddon::AutoStart(int in_index, BMediaNode ** out_node, return B_ERROR; *out_internal_id = 0; - AudioMixer *mixer = new AudioMixer(this); - - // disable stop on the auto started (system) mixer - mixer->DisableNodeStop(); - + AudioMixer *mixer = new AudioMixer(this, true); *out_node = mixer; return B_OK; diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp index e8805dc4b8..45f74cea38 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -100,23 +100,23 @@ MixerCore::SetOutputAttenuation(float gain) fOutputGain = gain; } -bool +MixerInput * MixerCore::AddInput(const media_input &input) { ASSERT_LOCKED(); - if (HasKawamba()) - fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate * 1.5, fMixBufferFrameCount * 2)); - else - fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount)); - return true; + MixerInput *in = new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount); + fInputs->AddItem(in); + return in; } -bool +MixerOutput * MixerCore::AddOutput(const media_output &output) { ASSERT_LOCKED(); - if (fOutput) - return false; + if (fOutput) { + ERROR("MixerCore::AddOutput: already connected\n"); + return fOutput; + } fOutput = new MixerOutput(this, output); // the output format might have been adjusted inside MixerOutput ApplyOutputFormat(); @@ -124,6 +124,8 @@ MixerCore::AddOutput(const media_output &output) ASSERT(!fRunning); if (fStarted && fOutputEnabled) StartMixThread(); + + return fOutput; } bool diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.h b/src/add-ons/media/media-add-ons/mixer/MixerCore.h index 069a719d8a..83c9e3514d 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.h @@ -29,8 +29,8 @@ public: // the audio mixer node using SetOutputAttenuation() void SetOutputAttenuation(float gain); - bool AddInput(const media_input &input); - bool AddOutput(const media_output &output); + MixerInput * AddInput(const media_input &input); + MixerOutput * AddOutput(const media_output &output); bool RemoveInput(int32 inputID); bool RemoveOutput(); diff --git a/src/add-ons/media/media-add-ons/mixer/MixerSettings.cpp b/src/add-ons/media/media-add-ons/mixer/MixerSettings.cpp index 1cc3048cd9..1f5d49605d 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerSettings.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerSettings.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "MixerCore.h" @@ -8,15 +9,17 @@ #include "MixerSettings.h" #include "debug.h" -#define SAVE_DELAY 8000000 // delay saving of settings for 8s -#define SAVE_RUNTIME 40000000 // stop save thread after 40s inactivity +#define SAVE_DELAY 5000000 // delay saving of settings for 5s +#define SAVE_RUNTIME 30000000 // stop save thread after 30s inactivity MixerSettings::MixerSettings() : fLocker(new BLocker), + fSettingsFile(0), fSettingsDirty(false), fSettingsLastChange(0), fSaveThread(-1), - fSaveThreadWaitSem(-1) + fSaveThreadWaitSem(-1), + fSaveThreadRunning(false) { Load(); } @@ -27,6 +30,16 @@ MixerSettings::~MixerSettings() if (fSettingsDirty) Save(); delete fLocker; + delete fSettingsFile; +} + +void +MixerSettings::SetSettingsFile(const char *file) +{ + fLocker->Lock(); + delete fSettingsFile; + fSettingsFile = new BPath(file); + fLocker->Unlock(); } bool @@ -201,27 +214,29 @@ MixerSettings::SetRefuseInputFormatChange(bool yesno) } void -MixerSettings::SaveGain(MixerInput *input) +MixerSettings::SaveConnectionSettings(MixerInput *input) +{ + StartDeferredSave(); +} + +void +MixerSettings::LoadConnectionSettings(MixerInput *input) { } void -MixerSettings::LoadGain(MixerInput *input) +MixerSettings::SaveConnectionSettings(MixerOutput *output) +{ + StartDeferredSave(); +} + +void +MixerSettings::LoadConnectionSettings(MixerOutput *output) { } void -MixerSettings::SaveGain(MixerOutput *output) -{ -} - -void -MixerSettings::LoadGain(MixerOutput *output) -{ -} - -void -MixerSettings::SaveGainSetting(const char *name, uint32 channel_mask, const float *gain, int gain_count) +MixerSettings::SaveConnectionSettingsSetting(const char *name, uint32 channel_mask, const float *gain, int gain_count) { fLocker->Lock(); @@ -232,7 +247,7 @@ MixerSettings::SaveGainSetting(const char *name, uint32 channel_mask, const floa } void -MixerSettings::LoadGainSetting(const char *name, uint32 channel_mask, float *gain, int gain_count) +MixerSettings::LoadConnectionSettingsSetting(const char *name, uint32 channel_mask, float *gain, int gain_count) { fLocker->Lock(); @@ -266,8 +281,15 @@ void MixerSettings::Save() { fLocker->Lock(); + // if we don't have a settings file, don't continue + if (!fSettingsFile) { + fLocker->Unlock(); + return; + } TRACE("MixerSettings: SAVE!\n"); + + // XXX work @@ -279,9 +301,7 @@ void MixerSettings::Load() { fLocker->Lock(); - - // XXX work - + // setup defaults fSettings.AttenuateOutput = true; fSettings.NonLinearGainSlider = true; fSettings.UseBalanceControl = false; @@ -292,6 +312,12 @@ MixerSettings::Load() fSettings.RefuseOutputFormatChange = false; fSettings.RefuseInputFormatChange = false; + // if we don't have a settings file, don't continue + if (!fSettingsFile) { + fLocker->Unlock(); + return; + } + fLocker->Unlock(); } @@ -299,29 +325,45 @@ void MixerSettings::StartDeferredSave() { fLocker->Lock(); + + // if we don't have a settings file, don't save the settings + if (!fSettingsFile) { + fLocker->Unlock(); + return; + } fSettingsDirty = true; fSettingsLastChange = system_time(); - if (fSaveThread < 0) { - ASSERT(fSaveThreadWaitSem < 0); - fSaveThreadWaitSem = create_sem(0, "save thread wait"); - if (fSaveThreadWaitSem < B_OK) { - ERROR("MixerSettings: can't create semaphore\n"); - Save(); - fLocker->Unlock(); - return; - } - fSaveThread = spawn_thread(_save_thread_, "deferred settings save", 7, this); - if (fSaveThread < B_OK) { - ERROR("MixerSettings: can't spawn thread\n"); - delete_sem(fSaveThreadWaitSem); - fSaveThreadWaitSem = -1; - Save(); - fLocker->Unlock(); - return; - } + if (fSaveThreadRunning) { + fLocker->Unlock(); + return; } + + StopDeferredSave(); + + ASSERT(fSaveThreadWaitSem < 0); + fSaveThreadWaitSem = create_sem(0, "save thread wait"); + if (fSaveThreadWaitSem < B_OK) { + ERROR("MixerSettings: can't create semaphore\n"); + Save(); + fLocker->Unlock(); + return; + } + ASSERT(fSaveThread < 0); + fSaveThread = spawn_thread(_save_thread_, "Attack of the Killer Tomatoes", 7, this); + if (fSaveThread < B_OK) { + ERROR("MixerSettings: can't spawn thread\n"); + delete_sem(fSaveThreadWaitSem); + fSaveThreadWaitSem = -1; + Save(); + fLocker->Unlock(); + return; + } + resume_thread(fSaveThread); + + fSaveThreadRunning = true; + fLocker->Unlock(); } @@ -374,6 +416,7 @@ MixerSettings::SaveThread() } if (delta > SAVE_RUNTIME) { + fSaveThreadRunning = false; fLocker->Unlock(); break; } diff --git a/src/add-ons/media/media-add-ons/mixer/MixerSettings.h b/src/add-ons/media/media-add-ons/mixer/MixerSettings.h index cddf7e2c46..d7806e7bb2 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerSettings.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerSettings.h @@ -9,6 +9,8 @@ class MixerSettings public: MixerSettings(); ~MixerSettings(); + + void SetSettingsFile(const char *file); bool AttenuateOutput(); void SetAttenuateOutput(bool yesno); @@ -37,16 +39,16 @@ public: bool RefuseInputFormatChange(); void SetRefuseInputFormatChange(bool yesno); - void SaveGain(MixerInput *input); - void LoadGain(MixerInput *input); + void SaveConnectionSettings(MixerInput *input); + void LoadConnectionSettings(MixerInput *input); - void SaveGain(MixerOutput *output); - void LoadGain(MixerOutput *output); + void SaveConnectionSettings(MixerOutput *output); + void LoadConnectionSettings(MixerOutput *output); protected: - void SaveGainSetting(const char *name, uint32 channel_mask, const float *gain, int gain_count); - void LoadGainSetting(const char *name, uint32 channel_mask, float *gain, int gain_count); + void SaveConnectionSettingsSetting(const char *name, uint32 channel_mask, const float *gain, int gain_count); + void LoadConnectionSettingsSetting(const char *name, uint32 channel_mask, float *gain, int gain_count); void SaveSetting(const char *name, int value); void LoadSetting(const char *name, int *value, int default_value = 0); @@ -61,11 +63,13 @@ protected: void SaveThread(); BLocker *fLocker; - bool fSettingsDirty; - bigtime_t fSettingsLastChange; - - thread_id fSaveThread; - sem_id fSaveThreadWaitSem; + BPath *fSettingsFile; + + volatile bool fSettingsDirty; + volatile bigtime_t fSettingsLastChange; + volatile thread_id fSaveThread; + volatile sem_id fSaveThreadWaitSem; + volatile bool fSaveThreadRunning; struct settings { @@ -80,7 +84,7 @@ protected: bool RefuseInputFormatChange; }; - settings fSettings; + volatile settings fSettings; }; #endif //_MIXER_SETTINGS_H