Fixed some debug macros.

Cleanup of MixerInput class.
Implemented output destination mapping controls.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3819 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2003-07-03 22:01:27 +00:00
parent 3161d380ef
commit 9c3be6a557
5 changed files with 190 additions and 154 deletions

View File

@ -883,7 +883,7 @@ status_t
AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
void *value, size_t *ioSize)
{
TRACE("GetParameterValue: id %ld, ioSize %ld\n", id, *ioSize);
TRACE("GetParameterValue: id 0x%08x, ioSize %ld\n", id, *ioSize);
int param = PARAM(id);
fCore->Lock();
if (param == 0) {
@ -922,7 +922,7 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
for (int i = 0; (input = fCore->Input(i)); i++)
if (input->ID() == param)
break;
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !input)
if (!input || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_DST_ENABLE(id) && !PARAM_IS_DST_GAIN(id)))
goto err;
if (PARAM_IS_MUTE(id)) {
// input mute control
@ -939,6 +939,18 @@ AudioMixer::GetParameterValue(int32 id, bigtime_t *last_change,
for (int chan = 0; chan < input->GetInputChannelCount(); chan++)
static_cast<float *>(value)[chan] = DB_TO_GAIN(input->GetInputChannelGain(chan));
}
if (PARAM_IS_DST_ENABLE(id)) {
if (*ioSize < sizeof(int32))
goto err;
*ioSize = sizeof(int32);
static_cast<int32 *>(value)[0] = input->HasInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
}
if (PARAM_IS_DST_GAIN(id)) {
if (*ioSize < sizeof(float))
goto err;
*ioSize = sizeof(float);
static_cast<float *>(value)[0] = GAIN_TO_PERCENT(input->GetInputChannelDestinationGain(PARAM_CHAN(id), PARAM_DST(id)));
}
}
*last_change = TimeSource()->Now(); // XXX we could do better
fCore->Unlock();
@ -952,7 +964,7 @@ void
AudioMixer::SetParameterValue(int32 id, bigtime_t when,
const void *value, size_t size)
{
TRACE("SetParameterValue: id %ld, size %ld\n", id, size);
TRACE("SetParameterValue: id 0x%08x, size %ld\n", id, size);
int param = PARAM(id);
fCore->Lock();
if (param == 0) {
@ -991,7 +1003,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
for (int i = 0; (input = fCore->Input(i)); i++)
if (input->ID() == param)
break;
if ((!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id)) || !input)
if (!input || (!PARAM_IS_MUTE(id) && !PARAM_IS_GAIN(id) && !PARAM_IS_DST_ENABLE(id) && !PARAM_IS_DST_GAIN(id)))
goto err;
if (PARAM_IS_MUTE(id)) {
// input mute control
@ -1006,6 +1018,34 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when,
for (int chan = 0; chan < input->GetInputChannelCount(); chan++)
input->SetInputChannelGain(chan, GAIN_TO_DB(static_cast<const float *>(value)[chan]));
}
if (PARAM_IS_DST_ENABLE(id)) {
if (size != sizeof(int32))
goto err;
if (static_cast<const int32 *>(value)[0]) {
int oldchan = input->GetInputChannelForDestination(PARAM_DST(id));
if (oldchan != -1) {
input->RemoveInputChannelDestination(oldchan, PARAM_DST(id));
int32 null = 0;
BroadcastNewParameterValue(when, PARAM_DST_ENABLE(PARAM(id), oldchan, PARAM_DST(id)), &null, sizeof(null));
}
input->AddInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
} else {
input->RemoveInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
}
}
if (PARAM_IS_DST_GAIN(id)) {
if (size != sizeof(float))
goto err;
input->SetInputChannelDestinationGain(PARAM_CHAN(id), PARAM_DST(id), PERCENT_TO_GAIN(static_cast<const float *>(value)[0]));
// We have an ugly display where each destination gain slider
// is diplayed for each input channel.
// Update all other sliders for this destination type
for (int chan = 0; chan < input->GetInputChannelCount(); chan++) {
if (PARAM_CHAN(id) == chan)
continue;
BroadcastNewParameterValue(when, PARAM_DST_GAIN(PARAM(id), chan, PARAM_DST(id)), const_cast<void *>(value), size);
}
}
}
BroadcastNewParameterValue(when, id, const_cast<void *>(value), size);
err:
@ -1077,10 +1117,10 @@ AudioMixer::UpdateParameterWeb()
}
}
#if 0
top = web->MakeGroup("Input Mapping"); // top level group
inputchannels = top->MakeGroup("");
inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC);
// inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations", B_GENERIC);
inputchannels->MakeNullParameter(PARAM_STR7(0), B_MEDIA_RAW_AUDIO, "Input Channel Destinations (PREVIEW; DISPLAYS ONLY ONE CONNECTED INPUT)", B_GENERIC);
// for (int i = 0; (in = fCore->Input(i)); i++) {
if ((in = fCore->Input(1)) || (in = fCore->Input(0))) { // XXX limited to input 1 or 0 to aviod BSlider problems
@ -1101,7 +1141,6 @@ AudioMixer::UpdateParameterWeb()
}
}
#endif
fCore->Unlock();

View File

@ -24,7 +24,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
fLastDataAvailableTime(-1),
fResampler(0),
fRtmPool(0),
fUserOverridesChannelDesignations(false)
fUserOverridesChannelDestinations(false)
{
fix_multiaudio_format(&fInput.format.u.raw_audio);
PRINT_INPUT("MixerInput::MixerInput", fInput);
@ -32,6 +32,9 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
ASSERT(fInput.format.u.raw_audio.channel_count > 0);
for (int i = 0; i < MAX_CHANNEL_TYPES; i++)
fChannelTypeGain[i] = 1.0f;
fInputChannelCount = fInput.format.u.raw_audio.channel_count;
fInputChannelMask = fInput.format.u.raw_audio.channel_mask;
fInputChannelInfo = new input_chan_info[fInputChannelCount];
@ -48,7 +51,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
// initialize fInputChannelInfo
for (int i = 0; i < fInputChannelCount; i++) {
fInputChannelInfo[i].buffer_base = 0; // will be set by SetMixBufferFormat()
fInputChannelInfo[i].designations = 0; // will be set by UpdateChannelDesignations()
fInputChannelInfo[i].destination_mask = 0; // will be set by UpdateInputChannelDestinationMask()
fInputChannelInfo[i].gain = 1.0;
}
@ -57,18 +60,9 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame
for (int i = 0; i < fInputChannelCount; i++)
fResampler[i] = new Resampler(fInput.format.u.raw_audio.format, media_raw_audio_format::B_AUDIO_FLOAT);
// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels()
// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateInputChannelDestinations()
SetMixBufferFormat(mixFrameRate, mixFrameCount);
// XXX a test:
/*
SetMixerChannelGain(0, 0.222);
SetMixerChannelGain(1, 0.444);
AddInputChannelDesignation(0, B_CHANNEL_REARRIGHT);
SetMixerChannelGain(2, 0.666);
AddInputChannelDesignation(1, B_CHANNEL_REARLEFT);
*/
}
MixerInput::~MixerInput()
@ -196,65 +190,81 @@ MixerInput::GetInputChannelCount()
}
void
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
MixerInput::AddInputChannelDestination(int channel, int destination_type)
{
ASSERT(count_nonzero_bits(des) == 1);
uint32 mask = ChannelTypeToChannelMask(destination_type);
// test if the channel is valid
if (channel < 0 || channel >= fInputChannelCount)
return;
// test if it is already set
if (fInputChannelInfo[channel].designations & des)
if (fInputChannelInfo[channel].destination_mask & mask)
return;
// remove it from all other channels that might have it
for (int i = 0; i < fInputChannelCount; i++)
fInputChannelInfo[i].designations &= ~des;
// add it to specified channel
fInputChannelInfo[channel].designations |= des;
// verify that no other channel has id
if (-1 != GetInputChannelForDestination(destination_type)) {
ERROR("MixerInput::AddInputChannelDestination: destination_type %d already assigned to channel %d\n", destination_type, GetInputChannelForDestination(destination_type));
return;
}
fUserOverridesChannelDesignations = true;
UpdateMixerChannels();
// add it to specified channel
fInputChannelInfo[channel].destination_mask |= mask;
fUserOverridesChannelDestinations = true;
UpdateInputChannelDestinations();
}
void
MixerInput::RemoveInputChannelDesignation(int channel, uint32 des)
MixerInput::RemoveInputChannelDestination(int channel, int destination_type)
{
ASSERT(count_nonzero_bits(des) == 1);
uint32 mask = ChannelTypeToChannelMask(destination_type);
// test if the channel is valid
if (channel < 0 || channel >= fInputChannelCount)
return;
// test if it is really set
if ((fInputChannelInfo[channel].designations & des) == 0)
if ((fInputChannelInfo[channel].destination_mask & mask) == 0)
return;
// remove it from specified channel
fInputChannelInfo[channel].designations &= ~des;
fInputChannelInfo[channel].destination_mask &= ~mask;
fUserOverridesChannelDesignations = true;
UpdateMixerChannels();
fUserOverridesChannelDestinations = true;
UpdateInputChannelDestinations();
}
uint32
MixerInput::GetInputChannelDesignations(int channel)
bool
MixerInput::HasInputChannelDestination(int channel, int destination_type)
{
// test if the channel is valid
if (channel < 0 || channel >= fInputChannelCount)
return 0;
return fInputChannelInfo[channel].designations;
return false;
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
return false;
return fInputChannelInfo[channel].destination_mask & ChannelTypeToChannelMask(destination_type);
}
uint32
int
MixerInput::GetInputChannelForDestination(int destination_type)
{
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
return -1;
uint32 mask = ChannelTypeToChannelMask(destination_type);
for (int chan = 0; chan < fInputChannelCount; chan++) {
if (fInputChannelInfo[chan].destination_mask & mask)
return chan;
}
return -1;
}
int
MixerInput::GetInputChannelType(int channel)
{
// test if the channel is valid
if (channel < 0 || channel >= fInputChannelCount)
return 0;
return GetChannelMask(channel, fInputChannelMask);
return GetChannelType(channel, fInputChannelMask);
}
void
@ -279,17 +289,17 @@ MixerInput::GetInputChannelGain(int channel)
}
void
MixerInput::UpdateChannelDesignations()
MixerInput::UpdateInputChannelDestinationMask()
{
// is the user already messed with the assignmens, don't do anything.
if (fUserOverridesChannelDesignations)
if (fUserOverridesChannelDestinations)
return;
TRACE("UpdateChannelDesignations: enter\n");
TRACE("UpdateInputChannelDestinationMask: enter\n");
// first apply a 1:1 mapping
for (int i = 0; i < fInputChannelCount; i++)
fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask);
fInputChannelInfo[i].destination_mask = GetChannelMask(i, fInputChannelMask);
// specialize this, depending on the available physical output channels
switch (fCore->OutputChannelCount()) {
@ -299,80 +309,70 @@ MixerInput::UpdateChannelDesignations()
case 2:
if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
}
break;
default:
if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
}
if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_LEFT)) {
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
fInputChannelInfo[0].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
}
if (fInputChannelCount == 2 && (GetChannelMask(0, fInputChannelMask) & B_CHANNEL_RIGHT)) {
fInputChannelInfo[0].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
fInputChannelInfo[0].destination_mask = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
}
if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_LEFT)) {
fInputChannelInfo[1].designations = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
fInputChannelInfo[1].destination_mask = B_CHANNEL_LEFT | B_CHANNEL_REARLEFT;
}
if (fInputChannelCount == 2 && (GetChannelMask(1, fInputChannelMask) & B_CHANNEL_RIGHT)) {
fInputChannelInfo[1].designations = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
fInputChannelInfo[1].destination_mask = B_CHANNEL_RIGHT | B_CHANNEL_REARRIGHT;
}
break;
}
for (int i = 0; i < fInputChannelCount; i++)
TRACE("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
TRACE("UpdateInputChannelDestinationMask: input channel %d, destination_mask 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
TRACE("UpdateChannelDesignations: leave\n");
TRACE("UpdateInputChannelDestinationMask: leave\n");
}
void
MixerInput::UpdateMixerChannels()
MixerInput::UpdateInputChannelDestinations()
{
uint32 channel_count;
uint32 all_bits;
uint32 mask;
mixer_chan_info *old_mixer_channel_info;
uint32 old_mixer_channel_count;
TRACE("UpdateMixerChannels: enter\n");
TRACE("UpdateInputChannelDestinations: enter\n");
for (int i = 0; i < fInputChannelCount; i++)
TRACE("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
TRACE("UpdateInputChannelDestinations: input channel %d, destination_mask 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].destination_mask, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
all_bits = 0;
for (int i = 0; i < fInputChannelCount; i++)
all_bits |= fInputChannelInfo[i].designations;
all_bits |= fInputChannelInfo[i].destination_mask;
TRACE("UpdateMixerChannels: all_bits = %08x\n", all_bits);
TRACE("UpdateInputChannelDestinations: all_bits = %08x\n", all_bits);
channel_count = count_nonzero_bits(all_bits);
TRACE("UpdateMixerChannels: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount);
TRACE("UpdateInputChannelDestinations: %ld input channels, %ld mixer channels (%ld old)\n", fInputChannelCount, channel_count, fMixerChannelCount);
// If we resize the channel info array, we preserve the gain setting
// by saving the old array until new assignments are finished, and
// then applying the old gains. New gains are set to 1.0
if (channel_count != fMixerChannelCount) {
old_mixer_channel_info = fMixerChannelInfo;
old_mixer_channel_count = fMixerChannelCount;
delete [] fMixerChannelInfo;
fMixerChannelInfo = new mixer_chan_info[channel_count];
fMixerChannelCount = channel_count;
for (int i = 0; i < fMixerChannelCount; i++)
fMixerChannelInfo[i].gain = 1.0;
} else {
old_mixer_channel_info = 0;
old_mixer_channel_count = 0;
}
// assign each mixer channel one type
// and the gain from the fChannelTypeGain[]
for (int i = 0, mask = 1; i < fMixerChannelCount; i++) {
while (mask != 0 && (all_bits & mask) == 0)
mask <<= 1;
fMixerChannelInfo[i].type = ChannelMaskToChannelType(mask);
fMixerChannelInfo[i].destination_type = ChannelMaskToChannelType(mask);
fMixerChannelInfo[i].destination_gain = fChannelTypeGain[fMixerChannelInfo[i].destination_type];
mask <<= 1;
}
@ -380,7 +380,7 @@ MixerInput::UpdateMixerChannels()
for (int i = 0; i < fMixerChannelCount; i++) {
int j;
for (j = 0; j < fInputChannelCount; j++) {
if (fInputChannelInfo[j].designations & ChannelTypeToChannelMask(fMixerChannelInfo[i].type)) {
if (fInputChannelInfo[j].destination_mask & ChannelTypeToChannelMask(fMixerChannelInfo[i].destination_type)) {
fMixerChannelInfo[i].buffer_base = fMixBuffer ? &fMixBuffer[j] : 0;
break;
}
@ -390,50 +390,46 @@ MixerInput::UpdateMixerChannels()
fMixerChannelInfo[i].buffer_base = fMixBuffer;
}
}
// apply old gains, overriding the 1.0 defaults for the old channels
if (old_mixer_channel_info != 0) {
for (int i = 0; i < fMixerChannelCount; i++) {
for (int j = 0; j < old_mixer_channel_count; j++) {
if (fMixerChannelInfo[i].type == old_mixer_channel_info[j].type) {
fMixerChannelInfo[i].gain = old_mixer_channel_info[j].gain;
break;
}
}
}
// also delete the old info array
delete [] old_mixer_channel_info;
}
for (int i = 0; i < fMixerChannelCount; i++)
TRACE("UpdateMixerChannels: mixer channel %d, type %2d, des 0x%08X, base %p, gain %.3f\n", i, fMixerChannelInfo[i].type, ChannelTypeToChannelMask(fMixerChannelInfo[i].type), fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].gain);
TRACE("UpdateInputChannelDestinations: mixer channel %d, type %2d, base %p, gain %.3f\n", i, fMixerChannelInfo[i].destination_type, fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].destination_gain);
TRACE("UpdateMixerChannels: leave\n");
}
uint32
MixerInput::GetMixerChannelCount()
{
return fMixerChannelCount;
TRACE("UpdateInputChannelDestinations: leave\n");
}
void
MixerInput::SetMixerChannelGain(int channel, float gain)
MixerInput::SetInputChannelDestinationGain(int channel, int destination_type, float gain)
{
TRACE("SetMixerChannelGain chan %d, gain %.5f\n", channel, gain);
TRACE("SetInputChannelDestinationGain: channel %d, destination_type %d, gain %.4f\n", channel, destination_type, gain);
// we don't need the channel, as each destination_type can only exist
// once for each MixerInput, but we use it for parameter validation
// and to have a interface similar to MixerOutput
if (channel < 0 || channel >= fMixerChannelCount)
return;
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
return;
if (gain < 0.0f)
gain = 0.0f;
fMixerChannelInfo[channel].gain = gain;
fChannelTypeGain[destination_type] = gain;
for (int i = 0; i < fMixerChannelCount; i++) {
if (fMixerChannelInfo[i].destination_type == destination_type) {
fMixerChannelInfo[i].destination_gain = gain;
return;
}
}
}
float
MixerInput::GetMixerChannelGain(int channel)
MixerInput::GetInputChannelDestinationGain(int channel, int destination_type)
{
// we don't need the channel, as each destination_type can only exist
// once for each MixerInput, but we use it for parameter validation
// and to have a interface similar to MixerOutput
if (channel < 0 || channel >= fMixerChannelCount)
return 1.0;
return fMixerChannelInfo[channel].gain;
return 0.0f;
if (destination_type < 0 || destination_type >= MAX_CHANNEL_TYPES)
return 0.0f;
return fChannelTypeGain[destination_type];
}
void
@ -466,8 +462,8 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
fInputChannelInfo[i].buffer_base = 0;
fMixBufferFrameCount = 0;
UpdateChannelDesignations();
UpdateMixerChannels();
UpdateInputChannelDestinationMask();
UpdateInputChannelDestinations();
return;
}
@ -502,6 +498,6 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames)
for (int i = 0; i < fInputChannelCount; i++)
fInputChannelInfo[i].buffer_base = &fMixBuffer[i];
UpdateChannelDesignations();
UpdateMixerChannels();
UpdateInputChannelDestinationMask();
UpdateInputChannelDestinations();
}

View File

@ -3,9 +3,9 @@
#include <RealtimeAlloc.h>
#include <MediaNode.h>
#include "MixerCore.h"
#include "debug.h"
class MixerCore;
class ByteSwap;
class Resampler;
@ -20,44 +20,46 @@ public:
void BufferReceived(BBuffer *buffer);
media_input & MediaInput();
uint32 GetMixerChannelCount();
void SetMixerChannelGain(int channel, float gain);
float GetMixerChannelGain(int channel);
uint32 GetInputChannelCount();
void AddInputChannelDesignation(int channel, uint32 des);
void RemoveInputChannelDesignation(int channel, uint32 des);
uint32 GetInputChannelDesignations(int channel);
uint32 GetInputChannelType(int channel);
void SetInputChannelGain(int channel, float gain);
float GetInputChannelGain(int channel);
// The physical input channels
uint32 GetInputChannelCount();
int GetInputChannelType(int channel);
void SetInputChannelGain(int channel, float gain);
float GetInputChannelGain(int channel);
// The destinations for each channel
void AddInputChannelDestination(int channel, int destination_type);
void RemoveInputChannelDestination(int channel, int destination_type);
void SetInputChannelDestinationGain(int channel, int destination_type, float gain);
float GetInputChannelDestinationGain(int channel, int destination_type);
bool HasInputChannelDestination(int channel, int destination_type);
int GetInputChannelForDestination(int destination_type); // returns -1 if not found
void SetEnabled(bool yesno);
bool IsEnabled();
// only for use by MixerCore
bool GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain);
int GetMixerChannelType(int channel);
uint32 GetMixerChannelCount();
bool GetMixerChannelInfo(int mixer_channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain);
protected:
friend class MixerCore;
void SetMixBufferFormat(int32 framerate, int32 frames);
private:
void UpdateChannelDesignations();
void UpdateMixerChannels();
void UpdateInputChannelDestinationMask();
void UpdateInputChannelDestinations();
private:
struct input_chan_info {
float *buffer_base;
uint32 designations; // multiple or no bits sets
uint32 destination_mask; // multiple or no bits sets
float gain;
};
struct mixer_chan_info {
float *buffer_base;
int type;
float gain;
int destination_type;
float destination_gain;
};
private:
@ -65,6 +67,8 @@ private:
media_input fInput;
ByteSwap *fInputByteSwap;
float fChannelTypeGain[MAX_CHANNEL_TYPES];
bool fEnabled;
input_chan_info *fInputChannelInfo; // array
@ -84,34 +88,32 @@ private:
Resampler **fResampler; // array
rtm_pool *fRtmPool;
bool fUserOverridesChannelDesignations;
bool fUserOverridesChannelDestinations;
int32 debugMixBufferFrames;
};
inline uint32
MixerInput::GetMixerChannelCount()
{
return fMixerChannelCount;
}
inline bool
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain)
MixerInput::GetMixerChannelInfo(int mixer_channel, int64 framepos, bigtime_t time, const float **buffer, uint32 *sample_offset, int *type, float *gain)
{
ASSERT(fMixBuffer); // this function should not be called if we don't have a mix buffer!
ASSERT(channel >= 0 && channel < fMixerChannelCount);
ASSERT(mixer_channel >= 0 && mixer_channel < fMixerChannelCount);
if (time > fLastDataAvailableTime || !fEnabled)
return false;
int32 offset = framepos % fMixBufferFrameCount;
if (channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
if (mixer_channel == 0) PRINT(3, "GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames - 1);
*buffer = reinterpret_cast<float *>(reinterpret_cast<char *>(fMixerChannelInfo[mixer_channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount));
*sample_offset = sizeof(float) * fInputChannelCount;
*type = fMixerChannelInfo[channel].type;
*gain = fMixerChannelInfo[channel].gain;
*type = fMixerChannelInfo[mixer_channel].destination_type;
*gain = fMixerChannelInfo[mixer_channel].destination_gain;
return true;
}
inline int
MixerInput::GetMixerChannelType(int channel)
{
ASSERT(fMixBuffer); // this function should not be called if we don't have a mix buffer!
ASSERT(channel >= 0 && channel < fMixerChannelCount);
return fMixerChannelInfo[channel].type;
}
#endif

View File

@ -104,7 +104,7 @@ MixerOutput::UpdateOutputChannels()
delete [] oldInfo;
}
for (int i = 0; i < fOutputChannelCount; i++)
TRACE("UpdateOutputChannels: output channel %d, des 0x%08X (type %2d), gain %.3f\n", i, fOutputChannelInfo[i].designation, ChannelMaskToChannelType(fOutputChannelInfo[i].designation), fOutputChannelInfo[i].gain);
TRACE("UpdateOutputChannels: output channel %d, type %2d, gain %.3f\n", i, fOutputChannelInfo[i].channel_type, fOutputChannelInfo[i].channel_gain);
}
void
@ -229,7 +229,7 @@ MixerOutput::AssignDefaultSources()
}
}
uint32
int
MixerOutput::GetOutputChannelType(int channel)
{
if (channel < 0 || channel >= fOutputChannelCount)

View File

@ -29,18 +29,18 @@ public:
// The physical output channels
uint32 GetOutputChannelCount();
uint32 GetOutputChannelType(int channel);
int GetOutputChannelType(int channel);
void SetOutputChannelGain(int channel, float gain);
float GetOutputChannelGain(int channel);
// The Sources for each channel
// The sources for each channel
void AddOutputChannelSource(int channel, int source_type);
void RemoveOutputChannelSource(int channel, int source_type);
void SetOutputChannelSourceGain(int channel, int source_type, float source_gain);
float GetOutputChannelSourceGain(int channel, int source_type);
bool HasOutputChannelSource(int channel, int source_type);
// The Output can be muted
// The output can be muted
void SetMuted(bool yesno);
bool IsMuted();
@ -61,7 +61,7 @@ private:
private:
/* An entry in the source array is not the same as the
* channel type, but the number should be the same
* channel type, but the count should be the same
*/
enum {
MAX_SOURCE_ENTRIES = MAX_CHANNEL_TYPES
@ -100,15 +100,14 @@ inline float MixerOutput::GetOutputChannelGain(int channel)
inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel)
{
if (channel < 0 || channel >= fOutputChannelCount)
return 0;
ASSERT(channel >= 0 && channel < fOutputChannelCount);
return fOutputChannelInfo[channel].source_count;
}
inline void MixerOutput::GetOutputChannelSourceInfoAt(int channel, int source_index, int *source_type, float *source_gain)
{
ASSERT(channel >= 0 && channel < fOutputChannelCount);
ASSERT(index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
ASSERT(source_index >= 0 && source_index < fOutputChannelInfo[channel].source_count);
*source_type = fOutputChannelInfo[channel].source_type[source_index];
*source_gain = fOutputChannelInfo[channel].source_gain[source_index];
}