added output channel control functions,

made most often called functions inline


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3746 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2003-06-29 20:03:44 +00:00
parent c303352a8e
commit fae6ce82e3
6 changed files with 253 additions and 23 deletions

View File

@ -465,19 +465,19 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
//printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency());
//SendLatencyChange(source, destination, EventLatency());
delete fBufferGroup;
fBufferGroup = CreateBufferGroup();
fCore->SetOutputBufferGroup(fBufferGroup);
// apply latency change
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
// apply format change
fCore->OutputFormatChanged(io_format->u.raw_audio);
delete fBufferGroup;
fBufferGroup = CreateBufferGroup();
fCore->SetOutputBufferGroup(fBufferGroup);
fCore->Unlock();
return B_OK;
err:
fCore->Unlock();
return B_ERROR;

View File

@ -204,7 +204,7 @@ MixerCore::ApplyOutputFormat()
delete fMixBufferChannelTypes;
fMixBufferFrameRate = (int32)format.frame_rate;
fMixBufferFrameRate = (int32)(0.5 + format.frame_rate);
fMixBufferFrameCount = frames_per_buffer(format);
if (fDoubleRateMixing) {
fMixBufferFrameRate *= 2;

View File

@ -189,6 +189,12 @@ MixerInput::ID()
return fInput.destination.id;
}
uint32
MixerInput::GetInputChannelCount()
{
return fInputChannelCount;
}
void
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
{
@ -385,19 +391,6 @@ MixerInput::GetMixerChannelCount()
return fMixerChannelCount;
}
void
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, 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);
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));
*sample_offset = sizeof(float) * fInputChannelCount;
*type = fMixerChannelInfo[channel].type;
*gain = fMixerChannelInfo[channel].gain;
}
void
MixerInput::SetMixerChannelGain(int channel, float gain)
{

View File

@ -1,6 +1,8 @@
#ifndef _MIXER_INPUT_H
#define _MIXER_INPUT_H
#include "debug.h"
class MixerCore;
class ByteSwap;
class Resampler;
@ -18,10 +20,10 @@ public:
media_input & MediaInput();
uint32 GetMixerChannelCount();
void GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain);
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);
@ -29,6 +31,10 @@ public:
void SetInputChannelGain(int channel, float gain);
float GetInputChannelGain(int channel);
// only for use by MixerCore
void GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain);
int GetMixerChannelType(int channel);
protected:
friend class MixerCore;
void SetMixBufferFormat(int32 framerate, int32 frames);
@ -74,4 +80,25 @@ private:
int32 debugMixBufferFrames;
};
inline void
MixerInput::GetMixerChannelInfo(int channel, int64 framepos, 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);
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));
*sample_offset = sizeof(float) * fInputChannelCount;
*type = fMixerChannelInfo[channel].type;
*gain = fMixerChannelInfo[channel].gain;
}
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

@ -6,15 +6,20 @@
MixerOutput::MixerOutput(MixerCore *core, const media_output &output)
: fCore(core),
fOutput(output)
fOutput(output),
fOutputChannelCount(0),
fOutputChannelInfo(0)
{
fix_multiaudio_format(&fOutput.format.u.raw_audio);
PRINT_OUTPUT("MixerOutput::MixerOutput", fOutput);
PRINT_CHANNEL_MASK(fOutput.format);
UpdateOutputChannels();
}
MixerOutput::~MixerOutput()
{
delete fOutputChannelInfo;
}
media_output &
@ -31,4 +36,148 @@ MixerOutput::ChangeFormat(const media_multi_audio_format &format)
PRINT_OUTPUT("MixerOutput::ChangeFormat", fOutput);
PRINT_CHANNEL_MASK(fOutput.format);
UpdateOutputChannels();
}
void
MixerOutput::UpdateOutputChannels()
{
output_chan_info *oldInfo = fOutputChannelInfo;
uint32 oldCount = fOutputChannelCount;
fOutputChannelCount = fOutput.format.u.raw_audio.channel_count;
fOutputChannelInfo = new output_chan_info[fOutputChannelCount];
for (int i = 0; i < fOutputChannelCount; i++) {
fOutputChannelInfo[i].designation = GetChannelMask(i, fOutput.format.u.raw_audio.channel_mask);
fOutputChannelInfo[i].gain = 1.0;
fOutputChannelInfo[i].source_count = 1;
fOutputChannelInfo[i].source_gain[0] = 1.0;
fOutputChannelInfo[i].source_type[0] = ChannelMaskToChannelType(fOutputChannelInfo[i].designation);
}
AssignDefaultSources();
// apply old gains and sources, overriding the 1.0 gain defaults for the old channels
if (oldInfo != 0 && oldCount != 0) {
for (int i = 0; i < fOutputChannelCount; i++) {
for (int j = 0; j < oldCount; j++) {
if (fOutputChannelInfo[i].designation == oldInfo[j].designation) {
fOutputChannelInfo[i].gain == oldInfo[j].gain;
fOutputChannelInfo[i].source_count == oldInfo[j].source_count;
for (int k = 0; k < fOutputChannelInfo[i].source_count; k++) {
fOutputChannelInfo[i].source_gain[k] == oldInfo[j].source_gain[k];
fOutputChannelInfo[i].source_type[k] == oldInfo[j].source_type[k];
}
break;
}
}
}
// also delete the old info array
delete [] oldInfo;
}
for (int i = 0; i < fOutputChannelCount; i++)
printf("UpdateOutputChannels: output channel %d, des 0x%08X (type %2d), gain %.3f\n", i, fOutputChannelInfo[i].designation, ChannelMaskToChannelType(fOutputChannelInfo[i].designation), fOutputChannelInfo[i].gain);
}
void
MixerOutput::AssignDefaultSources()
{
// XXX assign default sources
for (int i = 0; i < fOutputChannelCount; i++) {
for (int j = 0; j < fOutputChannelInfo[i].source_count; j++) {
printf("AssignDefaultSources: output channel %d, source %d: des 0x%08X (type %2d), gain %.3f\n", i, j, ChannelTypeToChannelMask(fOutputChannelInfo[i].source_type[j]), fOutputChannelInfo[i].source_type[j], fOutputChannelInfo[i].source_gain[j]);
}
}
}
uint32
MixerOutput::GetOutputChannelDesignation(int channel)
{
if (channel < 0 || channel >= fOutputChannelCount)
return 0;
return fOutputChannelInfo[channel].designation;
}
void
MixerOutput::SetOutputChannelGain(int channel, float gain)
{
if (channel < 0 || channel >= fOutputChannelCount)
return;
fOutputChannelInfo[channel].gain = gain;
}
void
MixerOutput::AddOutputChannelSource(int channel, uint32 source_designation, float source_gain)
{
if (channel < 0 || channel >= fOutputChannelCount)
return;
if (fOutputChannelInfo[channel].source_count == MAX_SOURCES)
return;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type)
return;
}
fOutputChannelInfo[channel].source_type[fOutputChannelInfo[channel].source_count] = source_type;
fOutputChannelInfo[channel].source_gain[fOutputChannelInfo[channel].source_count] = source_gain;
fOutputChannelInfo[channel].source_count++;
}
void
MixerOutput::RemoveOutputChannelSource(int channel, uint32 source_designation)
{
if (channel < 0 || channel >= fOutputChannelCount)
return;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) {
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_count--;
return;
}
}
}
void
MixerOutput::SetOutputChannelSourceGain(int channel, uint32 source_designation, float source_gain)
{
if (channel < 0 || channel >= fOutputChannelCount)
return;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) {
fOutputChannelInfo[channel].source_gain[i] = source_gain;
return;
}
}
}
float
MixerOutput::GetOutputChannelSourceGain(int channel, uint32 source_designation)
{
if (channel < 0 || channel >= fOutputChannelCount)
return 1.0;
int source_type = ChannelMaskToChannelType(source_designation);
for (int i = 0; i < fOutputChannelInfo[channel].source_count; i++) {
if (fOutputChannelInfo[channel].source_type[i] == source_type) {
return fOutputChannelInfo[channel].source_gain[i];
}
}
return 1.0;
}
void
MixerOutput::GetOutputChannelSourceAt(int channel, int index, uint32 *source_designation, float *source_gain)
{
if (channel < 0 || channel >= fOutputChannelCount)
return;
if (index >= fOutputChannelInfo[channel].source_count) {
// ERROR
*source_gain = 1.0;
*source_designation = 0;
return;
}
*source_gain = fOutputChannelInfo[channel].source_gain[index];
*source_designation = ChannelTypeToChannelMask(fOutputChannelInfo[channel].source_type[index]);
}

View File

@ -1,6 +1,10 @@
#ifndef _MIXER_OUTPUT_H
#define _MIXER_OUTPUT_H
#include "debug.h"
#define MAX_SOURCES 20
class MixerCore;
class MixerOutput
@ -13,9 +17,66 @@ public:
void ChangeFormat(const media_multi_audio_format &format);
uint32 GetOutputChannelCount();
uint32 GetOutputChannelDesignation(int channel);
void SetOutputChannelGain(int channel, float gain);
float GetOutputChannelGain(int channel);
uint32 GetOutputChannelSourceCount(int channel);
void AddOutputChannelSource(int channel, uint32 source_designation, float source_gain);
void RemoveOutputChannelSource(int channel, uint32 source_designation);
void SetOutputChannelSourceGain(int channel, uint32 source_designation, float source_gain);
float GetOutputChannelSourceGain(int channel, uint32 source_designation);
void GetOutputChannelSourceAt(int channel, int index, uint32 *source_designation, float *source_gain);
// only for use by MixerCore
void GetMixerChannelInfo(int channel, int index, int *type, float *gain);
private:
MixerCore *fCore;
media_output fOutput;
void UpdateOutputChannels();
void AssignDefaultSources();
private:
struct output_chan_info {
uint32 designation; // only one bit set
float gain;
int source_count;
float source_gain[MAX_SOURCES];
int source_type[MAX_SOURCES];
};
MixerCore *fCore;
media_output fOutput;
uint32 fOutputChannelCount;
output_chan_info *fOutputChannelInfo; //array
};
inline uint32 MixerOutput::GetOutputChannelCount()
{
return fOutputChannelCount;
}
inline float MixerOutput::GetOutputChannelGain(int channel)
{
if (channel < 0 || channel >= fOutputChannelCount)
return 1.0;
return fOutputChannelInfo[channel].gain;
}
inline uint32 MixerOutput::GetOutputChannelSourceCount(int channel)
{
if (channel < 0 || channel >= fOutputChannelCount)
return 0;
return fOutputChannelInfo[channel].source_count;
}
inline void MixerOutput::GetMixerChannelInfo(int channel, int index, int *type, float *gain)
{
ASSERT (channel >= 0 && channel < fOutputChannelCount);
ASSERT(index >= 0 && index < fOutputChannelInfo[channel].source_count);
*type = fOutputChannelInfo[channel].source_type[index];
*gain = fOutputChannelInfo[channel].source_gain[index];
}
#endif