introduce a gain cache for non active sources to allow changing of gain without activating them, and to avoid gain value beeing reset to 0.0 each time enable is cycled.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3814 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-07-03 01:05:21 +00:00
parent b6270d60b2
commit e0dc5b6d1f
3 changed files with 38 additions and 18 deletions
@@ -976,22 +976,15 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
if (size != sizeof(int32)) if (size != sizeof(int32))
goto err; goto err;
if (static_cast<const int32 *>(value)[0]) { if (static_cast<const int32 *>(value)[0]) {
output->AddOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id), 0.0); output->AddOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id));
} else { } else {
output->RemoveOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id)); output->RemoveOutputChannelSource(PARAM_CHAN(id), PARAM_SRC(id));
} }
// after adding/removing sources, reset gain to 0.0
float nullgain = 0.0;
BroadcastNewParameterValue(when, PARAM_SRC_GAIN(PARAM(id), PARAM_CHAN(id), PARAM_SRC(id)), &nullgain, sizeof(nullgain));
} }
if (PARAM_IS_SRC_GAIN(id)) { if (PARAM_IS_SRC_GAIN(id)) {
if (size != sizeof(float)) if (size != sizeof(float))
goto err; goto err;
if (!output->SetOutputChannelSourceGain(PARAM_CHAN(id), PARAM_SRC(id), PERCENT_TO_GAIN(static_cast<const float *>(value)[0]))) { output->SetOutputChannelSourceGain(PARAM_CHAN(id), PARAM_SRC(id), PERCENT_TO_GAIN(static_cast<const float *>(value)[0]));
// gain setting failed, reset to 0.0
float nullgain = 0.0;
BroadcastNewParameterValue(when, PARAM_SRC_GAIN(PARAM(id), PARAM_CHAN(id), PARAM_SRC(id)), &nullgain, sizeof(nullgain));
}
} }
} else { } else {
MixerInput *input; MixerInput *input;
@@ -75,7 +75,11 @@ MixerOutput::UpdateOutputChannels()
fOutputChannelInfo[i].source_count = 1; fOutputChannelInfo[i].source_count = 1;
fOutputChannelInfo[i].source_gain[0] = 1.0; fOutputChannelInfo[i].source_gain[0] = 1.0;
fOutputChannelInfo[i].source_type[0] = fOutputChannelInfo[i].channel_type; fOutputChannelInfo[i].source_type[0] = fOutputChannelInfo[i].channel_type;
// all the cached values are 0.0 for a new channel
for (int j = 0; j < MAX_CHANNEL_TYPES; j++)
fOutputChannelInfo[i].source_gain_cache[j] = 0.0;
} }
AssignDefaultSources(); AssignDefaultSources();
// apply old gains and sources, overriding the 1.0 gain defaults for the old channels // apply old gains and sources, overriding the 1.0 gain defaults for the old channels
@@ -89,6 +93,9 @@ MixerOutput::UpdateOutputChannels()
fOutputChannelInfo[i].source_gain[k] == oldInfo[j].source_gain[k]; fOutputChannelInfo[i].source_gain[k] == oldInfo[j].source_gain[k];
fOutputChannelInfo[i].source_type[k] == oldInfo[j].source_type[k]; fOutputChannelInfo[i].source_type[k] == oldInfo[j].source_type[k];
} }
// also copy the old gain cache
for (int k = 0; k < MAX_CHANNEL_TYPES; k++)
fOutputChannelInfo[i].source_gain_cache[k] = oldInfo[j].source_gain_cache[k];
break; break;
} }
} }
@@ -240,16 +247,20 @@ MixerOutput::SetOutputChannelGain(int channel, float gain)
} }
void void
MixerOutput::AddOutputChannelSource(int channel, int source_type, float source_gain) MixerOutput::AddOutputChannelSource(int channel, int source_type)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return; return;
if (source_type < 0 || source_type >= MAX_CHANNEL_TYPES)
return;
if (fOutputChannelInfo[channel].source_count == MAX_SOURCE_ENTRIES) if (fOutputChannelInfo[channel].source_count == MAX_SOURCE_ENTRIES)
return; return;
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) if (fOutputChannelInfo[channel].source_type[i] == source_type)
return; return;
} }
// when adding a new source, use the current gain value from cache
float source_gain = fOutputChannelInfo[channel].source_gain_cache[source_type];
fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count] = source_type; fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count] = source_type;
fOutputChannelInfo[channel].source_gain[fOutputChannelInfo[channel].source_count] = source_gain; fOutputChannelInfo[channel].source_gain[fOutputChannelInfo[channel].source_count] = source_gain;
fOutputChannelInfo[channel].source_count++; fOutputChannelInfo[channel].source_count++;
@@ -262,6 +273,9 @@ MixerOutput::RemoveOutputChannelSource(int channel, int source_type)
return; return;
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
// when removing a source, save the current gain value into the cache
fOutputChannelInfo[channel].source_gain_cache[source_type] = fOutputChannelInfo[channel].source_gain[i];
// remove the entry
fOutputChannelInfo[channel].source_type[i] = fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count - 1]; fOutputChannelInfo[channel].source_type[i] = fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count - 1];
fOutputChannelInfo[channel].source_gain[i] = fOutputChannelInfo[channel].source_gain[fOutputChannelInfo[channel].source_count - 1]; fOutputChannelInfo[channel].source_gain[i] = fOutputChannelInfo[channel].source_gain[fOutputChannelInfo[channel].source_count - 1];
fOutputChannelInfo[channel].source_count--; fOutputChannelInfo[channel].source_count--;
@@ -270,18 +284,22 @@ MixerOutput::RemoveOutputChannelSource(int channel, int source_type)
} }
} }
bool void
MixerOutput::SetOutputChannelSourceGain(int channel, int source_type, float source_gain) MixerOutput::SetOutputChannelSourceGain(int channel, int source_type, float source_gain)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return false; return;
// set gain for active source
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
fOutputChannelInfo[channel].source_gain[i] = source_gain; fOutputChannelInfo[channel].source_gain[i] = source_gain;
return true; return;
} }
} }
return false; // we don't have an active source of that type, save gain in cache
if (source_type < 0 || source_type >= MAX_CHANNEL_TYPES)
return;
fOutputChannelInfo[channel].source_gain_cache[source_type] = source_gain;
} }
float float
@@ -289,12 +307,16 @@ MixerOutput::GetOutputChannelSourceGain(int channel, int source_type)
{ {
if (channel < 0 || channel >= fOutputChannelCount) if (channel < 0 || channel >= fOutputChannelCount)
return 0.0; return 0.0;
// get gain for active source
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) { for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) { if (fOutputChannelInfo[channel].source_type[i] == source_type) {
return fOutputChannelInfo[channel].source_gain[i]; return fOutputChannelInfo[channel].source_gain[i];
} }
} }
return 0.0; // we don't have an active source of that type, get gain from cache
if (source_type < 0 || source_type >= MAX_CHANNEL_TYPES)
return 0.0;
return fOutputChannelInfo[channel].source_gain_cache[source_type];
} }
bool bool
@@ -10,7 +10,11 @@
* for fast data retrieval by the MixerCore, which * for fast data retrieval by the MixerCore, which
* will call GetOutputChannelSourceInfoAt() and * will call GetOutputChannelSourceInfoAt() and
* iterate through the first source_count array entries * iterate through the first source_count array entries
* for source_gain[] and source_type[] * for source_gain[] and source_type[] arrays, they are
* index by 0 to GetOutputChannelSourceCount() - 1.
* To allow gain change for not active sources,
* we use the source_gain_cache[] array that is indexed
* by source_type.
*/ */
class MixerOutput class MixerOutput
@@ -30,9 +34,9 @@ public:
float GetOutputChannelGain(int channel); float GetOutputChannelGain(int channel);
// The Sources for each channel // The Sources for each channel
void AddOutputChannelSource(int channel, int source_type, float source_gain); void AddOutputChannelSource(int channel, int source_type);
void RemoveOutputChannelSource(int channel, int source_type); void RemoveOutputChannelSource(int channel, int source_type);
bool SetOutputChannelSourceGain(int channel, int source_type, float source_gain); void SetOutputChannelSourceGain(int channel, int source_type, float source_gain);
float GetOutputChannelSourceGain(int channel, int source_type); float GetOutputChannelSourceGain(int channel, int source_type);
bool HasOutputChannelSource(int channel, int source_type); bool HasOutputChannelSource(int channel, int source_type);
@@ -69,6 +73,7 @@ private:
int source_count; int source_count;
float source_gain[MAX_SOURCE_ENTRIES]; float source_gain[MAX_SOURCE_ENTRIES];
int source_type[MAX_SOURCE_ENTRIES]; int source_type[MAX_SOURCE_ENTRIES];
float source_gain_cache[MAX_CHANNEL_TYPES];
}; };
MixerCore *fCore; MixerCore *fCore;