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:
parent
c303352a8e
commit
fae6ce82e3
@ -465,19 +465,19 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
|
|||||||
//printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency());
|
//printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency());
|
||||||
//SendLatencyChange(source, destination, EventLatency());
|
//SendLatencyChange(source, destination, EventLatency());
|
||||||
|
|
||||||
delete fBufferGroup;
|
|
||||||
fBufferGroup = CreateBufferGroup();
|
|
||||||
fCore->SetOutputBufferGroup(fBufferGroup);
|
|
||||||
|
|
||||||
// apply latency change
|
// apply latency change
|
||||||
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
|
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
|
||||||
|
|
||||||
// apply format change
|
// apply format change
|
||||||
fCore->OutputFormatChanged(io_format->u.raw_audio);
|
fCore->OutputFormatChanged(io_format->u.raw_audio);
|
||||||
|
|
||||||
|
delete fBufferGroup;
|
||||||
|
fBufferGroup = CreateBufferGroup();
|
||||||
|
fCore->SetOutputBufferGroup(fBufferGroup);
|
||||||
|
|
||||||
fCore->Unlock();
|
fCore->Unlock();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
fCore->Unlock();
|
fCore->Unlock();
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
@ -204,7 +204,7 @@ MixerCore::ApplyOutputFormat()
|
|||||||
|
|
||||||
delete fMixBufferChannelTypes;
|
delete fMixBufferChannelTypes;
|
||||||
|
|
||||||
fMixBufferFrameRate = (int32)format.frame_rate;
|
fMixBufferFrameRate = (int32)(0.5 + format.frame_rate);
|
||||||
fMixBufferFrameCount = frames_per_buffer(format);
|
fMixBufferFrameCount = frames_per_buffer(format);
|
||||||
if (fDoubleRateMixing) {
|
if (fDoubleRateMixing) {
|
||||||
fMixBufferFrameRate *= 2;
|
fMixBufferFrameRate *= 2;
|
||||||
|
@ -189,6 +189,12 @@ MixerInput::ID()
|
|||||||
return fInput.destination.id;
|
return fInput.destination.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
MixerInput::GetInputChannelCount()
|
||||||
|
{
|
||||||
|
return fInputChannelCount;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
|
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
|
||||||
{
|
{
|
||||||
@ -385,19 +391,6 @@ MixerInput::GetMixerChannelCount()
|
|||||||
return fMixerChannelCount;
|
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
|
void
|
||||||
MixerInput::SetMixerChannelGain(int channel, float gain)
|
MixerInput::SetMixerChannelGain(int channel, float gain)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef _MIXER_INPUT_H
|
#ifndef _MIXER_INPUT_H
|
||||||
#define _MIXER_INPUT_H
|
#define _MIXER_INPUT_H
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
class MixerCore;
|
class MixerCore;
|
||||||
class ByteSwap;
|
class ByteSwap;
|
||||||
class Resampler;
|
class Resampler;
|
||||||
@ -18,10 +20,10 @@ public:
|
|||||||
media_input & MediaInput();
|
media_input & MediaInput();
|
||||||
|
|
||||||
uint32 GetMixerChannelCount();
|
uint32 GetMixerChannelCount();
|
||||||
void GetMixerChannelInfo(int channel, int64 framepos, const float **buffer, uint32 *sample_offset, int *type, float *gain);
|
|
||||||
void SetMixerChannelGain(int channel, float gain);
|
void SetMixerChannelGain(int channel, float gain);
|
||||||
float GetMixerChannelGain(int channel);
|
float GetMixerChannelGain(int channel);
|
||||||
|
|
||||||
|
uint32 GetInputChannelCount();
|
||||||
void AddInputChannelDesignation(int channel, uint32 des);
|
void AddInputChannelDesignation(int channel, uint32 des);
|
||||||
void RemoveInputChannelDesignation(int channel, uint32 des);
|
void RemoveInputChannelDesignation(int channel, uint32 des);
|
||||||
uint32 GetInputChannelDesignations(int channel);
|
uint32 GetInputChannelDesignations(int channel);
|
||||||
@ -29,6 +31,10 @@ public:
|
|||||||
void SetInputChannelGain(int channel, float gain);
|
void SetInputChannelGain(int channel, float gain);
|
||||||
float GetInputChannelGain(int channel);
|
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:
|
protected:
|
||||||
friend class MixerCore;
|
friend class MixerCore;
|
||||||
void SetMixBufferFormat(int32 framerate, int32 frames);
|
void SetMixBufferFormat(int32 framerate, int32 frames);
|
||||||
@ -74,4 +80,25 @@ private:
|
|||||||
int32 debugMixBufferFrames;
|
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
|
#endif
|
||||||
|
@ -6,15 +6,20 @@
|
|||||||
|
|
||||||
MixerOutput::MixerOutput(MixerCore *core, const media_output &output)
|
MixerOutput::MixerOutput(MixerCore *core, const media_output &output)
|
||||||
: fCore(core),
|
: fCore(core),
|
||||||
fOutput(output)
|
fOutput(output),
|
||||||
|
fOutputChannelCount(0),
|
||||||
|
fOutputChannelInfo(0)
|
||||||
{
|
{
|
||||||
fix_multiaudio_format(&fOutput.format.u.raw_audio);
|
fix_multiaudio_format(&fOutput.format.u.raw_audio);
|
||||||
PRINT_OUTPUT("MixerOutput::MixerOutput", fOutput);
|
PRINT_OUTPUT("MixerOutput::MixerOutput", fOutput);
|
||||||
PRINT_CHANNEL_MASK(fOutput.format);
|
PRINT_CHANNEL_MASK(fOutput.format);
|
||||||
|
|
||||||
|
UpdateOutputChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
MixerOutput::~MixerOutput()
|
MixerOutput::~MixerOutput()
|
||||||
{
|
{
|
||||||
|
delete fOutputChannelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
media_output &
|
media_output &
|
||||||
@ -31,4 +36,148 @@ MixerOutput::ChangeFormat(const media_multi_audio_format &format)
|
|||||||
|
|
||||||
PRINT_OUTPUT("MixerOutput::ChangeFormat", fOutput);
|
PRINT_OUTPUT("MixerOutput::ChangeFormat", fOutput);
|
||||||
PRINT_CHANNEL_MASK(fOutput.format);
|
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]);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#ifndef _MIXER_OUTPUT_H
|
#ifndef _MIXER_OUTPUT_H
|
||||||
#define _MIXER_OUTPUT_H
|
#define _MIXER_OUTPUT_H
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define MAX_SOURCES 20
|
||||||
|
|
||||||
class MixerCore;
|
class MixerCore;
|
||||||
|
|
||||||
class MixerOutput
|
class MixerOutput
|
||||||
@ -13,9 +17,66 @@ public:
|
|||||||
|
|
||||||
void ChangeFormat(const media_multi_audio_format &format);
|
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:
|
private:
|
||||||
MixerCore *fCore;
|
void UpdateOutputChannels();
|
||||||
media_output fOutput;
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user