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());
|
||||
//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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user