mixer input buffer assignment and gain setting implemented
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3585 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
#include "MixerCore.h"
|
#include "MixerCore.h"
|
||||||
#include "MixerInput.h"
|
#include "MixerInput.h"
|
||||||
#include "MixerOutput.h"
|
#include "MixerOutput.h"
|
||||||
|
#include "MixerUtils.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
|
||||||
#define MAX_OUTPUT_BUFFER_LENGTH 50000LL /* 50 ms */
|
#define MAX_OUTPUT_BUFFER_LENGTH 50000LL /* 50 ms */
|
||||||
@@ -12,6 +13,8 @@ MixerCore::MixerCore()
|
|||||||
: fLocker(new BLocker),
|
: fLocker(new BLocker),
|
||||||
fOutputBufferLength(MAX_OUTPUT_BUFFER_LENGTH),
|
fOutputBufferLength(MAX_OUTPUT_BUFFER_LENGTH),
|
||||||
fInputBufferLength(3 * MAX_OUTPUT_BUFFER_LENGTH),
|
fInputBufferLength(3 * MAX_OUTPUT_BUFFER_LENGTH),
|
||||||
|
fMixFrameRate(96000),
|
||||||
|
fMixStartTime(0),
|
||||||
fInputs(new BList),
|
fInputs(new BList),
|
||||||
fOutput(0),
|
fOutput(0),
|
||||||
fNextInputID(1),
|
fNextInputID(1),
|
||||||
@@ -24,12 +27,12 @@ MixerCore::~MixerCore()
|
|||||||
delete fLocker;
|
delete fLocker;
|
||||||
delete fInputs;
|
delete fInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MixerCore::AddInput(const media_input &input)
|
MixerCore::AddInput(const media_input &input)
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
fInputs->AddItem(new MixerInput(this, input));
|
fInputs->AddItem(new MixerInput(this, input, fMixFrameRate, frames_for_duration(fMixFrameRate, fInputBufferLength), fMixStartTime));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +108,9 @@ void
|
|||||||
MixerCore::OutputFormatChanged(const media_format *format)
|
MixerCore::OutputFormatChanged(const media_format *format)
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
|
|
||||||
|
void ChangeMixBufferFormat(float samplerate, int32 frames, int32 channelcount, uint32 channel_mask);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -165,7 +171,6 @@ MixerCore::OutputBufferLengthChanged(bigtime_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void BufferReceived(BBuffer *buffer, bigtime_t lateness);
|
void BufferReceived(BBuffer *buffer, bigtime_t lateness);
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public:
|
|||||||
|
|
||||||
uint32 OutputBufferSize();
|
uint32 OutputBufferSize();
|
||||||
bool IsStarted();
|
bool IsStarted();
|
||||||
|
|
||||||
|
uint32 OutputChannelCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OutputBufferLengthChanged(bigtime_t length);
|
void OutputBufferLengthChanged(bigtime_t length);
|
||||||
@@ -55,6 +57,8 @@ private:
|
|||||||
|
|
||||||
bigtime_t fOutputBufferLength;
|
bigtime_t fOutputBufferLength;
|
||||||
bigtime_t fInputBufferLength;
|
bigtime_t fInputBufferLength;
|
||||||
|
float fMixFrameRate;
|
||||||
|
bigtime_t fMixStartTime;
|
||||||
|
|
||||||
BList *fInputs;
|
BList *fInputs;
|
||||||
MixerOutput *fOutput;
|
MixerOutput *fOutput;
|
||||||
|
|||||||
@@ -1,25 +1,71 @@
|
|||||||
#include <MediaNode.h>
|
#include <MediaNode.h>
|
||||||
|
#include <Buffer.h>
|
||||||
|
#include <RealtimeAlloc.h>
|
||||||
#include "MixerInput.h"
|
#include "MixerInput.h"
|
||||||
#include "MixerCore.h"
|
#include "MixerCore.h"
|
||||||
#include "MixerUtils.h"
|
#include "MixerUtils.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
MixerInput::MixerInput(MixerCore *core, const media_input &input)
|
MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, bigtime_t mixStartTime)
|
||||||
: fCore(core),
|
: fCore(core),
|
||||||
fInput(input)
|
fInput(input),
|
||||||
|
fInputChannelInfo(0),
|
||||||
|
fInputChannelCount(0),
|
||||||
|
fInputChannelMask(0),
|
||||||
|
fMixerChannelInfo(0),
|
||||||
|
fMixerChannelCount(0),
|
||||||
|
fMixBuffer(0),
|
||||||
|
fMixBufferSampleRate(0),
|
||||||
|
fMixBufferFrames(0),
|
||||||
|
fMixBufferStartTime(0),
|
||||||
|
fUserOverridesChannelDesignations(false)
|
||||||
{
|
{
|
||||||
fix_multiaudio_format(&fInput.format.u.raw_audio);
|
fix_multiaudio_format(&fInput.format.u.raw_audio);
|
||||||
PRINT_INPUT("MixerInput::MixerInput", fInput);
|
PRINT_INPUT("MixerInput::MixerInput", fInput);
|
||||||
PRINT_CHANNEL_MASK(fInput.format);
|
PRINT_CHANNEL_MASK(fInput.format);
|
||||||
|
|
||||||
|
ASSERT(fInput.format.u.raw_audio.channel_count > 0);
|
||||||
|
|
||||||
|
fInputChannelCount = fInput.format.u.raw_audio.channel_count;
|
||||||
|
fInputChannelMask = fInput.format.u.raw_audio.channel_mask;
|
||||||
|
fInputChannelInfo = new input_chan_info[fInputChannelCount];
|
||||||
|
|
||||||
|
// 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].gain = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels()
|
||||||
|
|
||||||
|
SetMixBufferFormat(mixSampleRate, mixFramesCount, mixStartTime);
|
||||||
|
UpdateChannelDesignations();
|
||||||
|
UpdateMixerChannels();
|
||||||
|
|
||||||
|
|
||||||
|
// 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()
|
MixerInput::~MixerInput()
|
||||||
{
|
{
|
||||||
|
if (fMixBuffer)
|
||||||
|
rtm_free(fMixBuffer);
|
||||||
|
delete [] fInputChannelInfo;
|
||||||
|
delete [] fMixerChannelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MixerInput::BufferReceived(BBuffer *buffer)
|
MixerInput::BufferReceived(BBuffer *buffer)
|
||||||
{
|
{
|
||||||
|
ASSERT(fMixBuffer);
|
||||||
|
|
||||||
|
printf("mix buffer start %14Ld, buffer start %14Ld\n", fMixBufferStartTime, buffer->Header()->start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
media_input &
|
media_input &
|
||||||
@@ -34,4 +80,244 @@ MixerInput::ID()
|
|||||||
return fInput.destination.id;
|
return fInput.destination.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::AddInputChannelDesignation(int channel, uint32 des)
|
||||||
|
{
|
||||||
|
ASSERT(count_nonzero_bits(des) == 1);
|
||||||
|
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// test if it is already set
|
||||||
|
if (fInputChannelInfo[channel].designations & des)
|
||||||
|
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;
|
||||||
|
|
||||||
|
fUserOverridesChannelDesignations = true;
|
||||||
|
UpdateMixerChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::RemoveInputChannelDesignation(int channel, uint32 des)
|
||||||
|
{
|
||||||
|
ASSERT(count_nonzero_bits(des) == 1);
|
||||||
|
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// test if it is really set
|
||||||
|
if ((fInputChannelInfo[channel].designations & des) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// remove it from specified channel
|
||||||
|
fInputChannelInfo[channel].designations &= ~des;
|
||||||
|
|
||||||
|
fUserOverridesChannelDesignations = true;
|
||||||
|
UpdateMixerChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
MixerInput::GetInputChannelDesignations(int channel)
|
||||||
|
{
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return 0;
|
||||||
|
return fInputChannelInfo[channel].designations;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
MixerInput::GetInputChannelType(int channel)
|
||||||
|
{
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return 0;
|
||||||
|
return GetChannelMask(channel, fInputChannelMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::SetInputChannelGain(int channel, float gain)
|
||||||
|
{
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return;
|
||||||
|
if (gain < 0.0f)
|
||||||
|
gain = 0.0f;
|
||||||
|
|
||||||
|
fInputChannelInfo[channel].gain = gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
MixerInput::GetInputChannelGain(int channel)
|
||||||
|
{
|
||||||
|
// test if the channel is valid
|
||||||
|
if (channel < 0 || channel >= fInputChannelCount)
|
||||||
|
return 0.0f;
|
||||||
|
return fInputChannelInfo[channel].gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::UpdateChannelDesignations()
|
||||||
|
{
|
||||||
|
// is the user already messed with the assignmens, don't do anything.
|
||||||
|
if (fUserOverridesChannelDesignations)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("UpdateChannelDesignations: enter\n");
|
||||||
|
|
||||||
|
if (fInputChannelCount == 1 && (GetChannelMask(0, fInputChannelMask) & (B_CHANNEL_LEFT | B_CHANNEL_RIGHT))) {
|
||||||
|
// a left or right channel get's output as stereo on both
|
||||||
|
fInputChannelInfo[0].designations = B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
|
||||||
|
} else {
|
||||||
|
// everything else get's mapped 1:1
|
||||||
|
for (int i = 0; i < fInputChannelCount; i++)
|
||||||
|
fInputChannelInfo[i].designations = GetChannelMask(i, fInputChannelMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < fInputChannelCount; i++)
|
||||||
|
printf("UpdateChannelDesignations: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||||
|
|
||||||
|
printf("UpdateChannelDesignations: enter\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::UpdateMixerChannels()
|
||||||
|
{
|
||||||
|
uint32 channel_count;
|
||||||
|
uint32 all_bits;
|
||||||
|
uint32 mask;
|
||||||
|
|
||||||
|
mixer_chan_info *old_mixer_channel_info;
|
||||||
|
uint32 old_mixer_channel_count;
|
||||||
|
|
||||||
|
ASSERT(fMixBuffer);
|
||||||
|
|
||||||
|
printf("UpdateMixerChannels: enter\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < fInputChannelCount; i++)
|
||||||
|
printf("UpdateMixerChannels: input channel %d, designations 0x%08X, base %p, gain %.3f\n", i, fInputChannelInfo[i].designations, fInputChannelInfo[i].buffer_base, fInputChannelInfo[i].gain);
|
||||||
|
|
||||||
|
all_bits = 0;
|
||||||
|
for (int i = 0; i < fInputChannelCount; i++)
|
||||||
|
all_bits |= fInputChannelInfo[i].designations;
|
||||||
|
|
||||||
|
printf("UpdateMixerChannels: all_bits = %08x\n", all_bits);
|
||||||
|
|
||||||
|
channel_count = count_nonzero_bits(all_bits);
|
||||||
|
|
||||||
|
printf("UpdateMixerChannels: %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;
|
||||||
|
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
|
||||||
|
for (int i = 0, mask = 1; i < fMixerChannelCount; i++) {
|
||||||
|
while (mask != 0 && (all_bits & mask) == 0)
|
||||||
|
mask <<= 1;
|
||||||
|
fMixerChannelInfo[i].designation = mask;
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign buffer_base pointer for each mixer channel
|
||||||
|
for (int i = 0; i < fMixerChannelCount; i++) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < fInputChannelCount; j++) {
|
||||||
|
if (fInputChannelInfo[j].designations & fMixerChannelInfo[i].designation) {
|
||||||
|
fMixerChannelInfo[i].buffer_base = &fMixBuffer[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == fInputChannelCount) {
|
||||||
|
printf("buffer assignment failed for mixer chan %d\n", i);
|
||||||
|
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].designation == old_mixer_channel_info[j].designation) {
|
||||||
|
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++)
|
||||||
|
printf("UpdateMixerChannels: mixer channel %d, designation 0x%08X, base %p, gain %.3f\n", i, fMixerChannelInfo[i].designation, fMixerChannelInfo[i].buffer_base, fMixerChannelInfo[i].gain);
|
||||||
|
|
||||||
|
printf("UpdateMixerChannels: leave\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
MixerInput::GetMixerChannelCount()
|
||||||
|
{
|
||||||
|
return fMixerChannelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::GetMixerChannelInfo(int channel, const float **buffer, uint32 *sample_offset, uint32 *type, float *gain)
|
||||||
|
{
|
||||||
|
ASSERT(fMixBuffer);
|
||||||
|
ASSERT(channel >= 0 && channel < fMixerChannelCount);
|
||||||
|
*buffer = fMixerChannelInfo[channel].buffer_base;
|
||||||
|
*sample_offset = sizeof(float) * fInputChannelCount;
|
||||||
|
*type = fMixerChannelInfo[channel].designation;
|
||||||
|
*gain = fMixerChannelInfo[channel].gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::SetMixerChannelGain(int channel, float gain)
|
||||||
|
{
|
||||||
|
if (channel < 0 || channel >= fMixerChannelCount)
|
||||||
|
return;
|
||||||
|
if (gain < 0.0f)
|
||||||
|
gain = 0.0f;
|
||||||
|
fMixerChannelInfo[channel].gain = gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
MixerInput::GetMixerChannelGain(int channel)
|
||||||
|
{
|
||||||
|
if (channel < 0 || channel >= fMixerChannelCount)
|
||||||
|
return 1.0;
|
||||||
|
return fMixerChannelInfo[channel].gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MixerInput::SetMixBufferFormat(float samplerate, int32 frames, bigtime_t starttime)
|
||||||
|
{
|
||||||
|
fMixBufferSampleRate = samplerate;
|
||||||
|
fMixBufferFrames = frames;
|
||||||
|
fMixBufferStartTime = starttime;
|
||||||
|
|
||||||
|
if (fMixBuffer)
|
||||||
|
rtm_free(fMixBuffer);
|
||||||
|
fMixBuffer = (float *)rtm_alloc(NULL, sizeof(float) * fInputChannelCount * fMixBufferFrames);
|
||||||
|
|
||||||
|
for (int i = 0; i < fInputChannelCount; i++)
|
||||||
|
fInputChannelInfo[i].buffer_base = &fMixBuffer[i * fMixBufferFrames];
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class MixerCore;
|
|||||||
class MixerInput
|
class MixerInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MixerInput(MixerCore *core, const media_input &input);
|
MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, bigtime_t mixStartTime);
|
||||||
~MixerInput();
|
~MixerInput();
|
||||||
|
|
||||||
int32 ID();
|
int32 ID();
|
||||||
@@ -15,9 +15,56 @@ public:
|
|||||||
|
|
||||||
media_input & MediaInput();
|
media_input & MediaInput();
|
||||||
|
|
||||||
|
uint32 GetMixerChannelCount();
|
||||||
|
void GetMixerChannelInfo(int channel, const float **buffer, uint32 *sample_offset, uint32 *type, float *gain);
|
||||||
|
void SetMixerChannelGain(int channel, float gain);
|
||||||
|
float GetMixerChannelGain(int channel);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class MixerCore;
|
||||||
|
void SetMixBufferFormat(float samplerate, int32 frames, bigtime_t starttime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MixerCore *fCore;
|
void UpdateChannelDesignations();
|
||||||
media_input fInput;
|
void UpdateMixerChannels();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct input_chan_info {
|
||||||
|
float *buffer_base;
|
||||||
|
uint32 designations; // multiple or no bits sets
|
||||||
|
float gain;
|
||||||
|
};
|
||||||
|
struct mixer_chan_info {
|
||||||
|
float *buffer_base;
|
||||||
|
uint32 designation; // only one bit is set
|
||||||
|
float gain;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
MixerCore *fCore;
|
||||||
|
media_input fInput;
|
||||||
|
|
||||||
|
input_chan_info *fInputChannelInfo; // array
|
||||||
|
uint32 fInputChannelCount;
|
||||||
|
uint32 fInputChannelMask;
|
||||||
|
|
||||||
|
mixer_chan_info *fMixerChannelInfo; // array
|
||||||
|
uint32 fMixerChannelCount;
|
||||||
|
|
||||||
|
float *fMixBuffer;
|
||||||
|
|
||||||
|
float fMixBufferSampleRate;
|
||||||
|
uint32 fMixBufferFrames;
|
||||||
|
bigtime_t fMixBufferStartTime;
|
||||||
|
|
||||||
|
bool fUserOverridesChannelDesignations;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "MixerUtils.h"
|
#include "MixerUtils.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
void string_for_channel_mask(char *str, uint32 mask)
|
void
|
||||||
|
string_for_channel_mask(char *str, uint32 mask)
|
||||||
{
|
{
|
||||||
str[0] = 0;
|
str[0] = 0;
|
||||||
if (mask == 0) {
|
if (mask == 0) {
|
||||||
@@ -36,7 +38,8 @@ void string_for_channel_mask(char *str, uint32 mask)
|
|||||||
sprintf(str + strlen(str), "0x%08X", mask);
|
sprintf(str + strlen(str), "0x%08X", mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
int count_nonzero_bits(uint32 value)
|
int
|
||||||
|
count_nonzero_bits(uint32 value)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
@@ -45,7 +48,8 @@ int count_nonzero_bits(uint32 value)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fix_multiaudio_format(media_multi_audio_format *format)
|
void
|
||||||
|
fix_multiaudio_format(media_multi_audio_format *format)
|
||||||
{
|
{
|
||||||
if (format->format == media_raw_audio_format::B_AUDIO_INT) {
|
if (format->format == media_raw_audio_format::B_AUDIO_INT) {
|
||||||
if (format->valid_bits != 0 && (format->valid_bits < 16 || format->valid_bits >= 32))
|
if (format->valid_bits != 0 && (format->valid_bits < 16 || format->valid_bits >= 32))
|
||||||
@@ -68,6 +72,12 @@ void fix_multiaudio_format(media_multi_audio_format *format)
|
|||||||
format->matrix_mask = 0;
|
format->matrix_mask = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
if (count_nonzero_bits(format->channel_mask) != 3) {
|
||||||
|
format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_CENTER;
|
||||||
|
format->matrix_mask = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (count_nonzero_bits(format->channel_mask) != 4) {
|
if (count_nonzero_bits(format->channel_mask) != 4) {
|
||||||
format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
|
format->channel_mask = B_CHANNEL_LEFT | B_CHANNEL_RIGHT | B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT;
|
||||||
@@ -92,5 +102,45 @@ void fix_multiaudio_format(media_multi_audio_format *format)
|
|||||||
format->matrix_mask = 0;
|
format->matrix_mask = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
GetChannelMask(int channel, uint32 all_channel_masks)
|
||||||
|
{
|
||||||
|
ASSERT(channel <= count_nonzero_bits(all_channel_masks));
|
||||||
|
|
||||||
|
uint32 mask = 1;
|
||||||
|
int pos = 0;
|
||||||
|
for (;;) {
|
||||||
|
while ((all_channel_masks & mask) == 0)
|
||||||
|
mask <<= 1;
|
||||||
|
if (pos == channel)
|
||||||
|
return mask;
|
||||||
|
pos++;
|
||||||
|
mask <<= 1;
|
||||||
|
if (mask == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CopySamples(float *_dst, int32 _dst_sample_offset,
|
||||||
|
const float *_src, int32 _src_sample_offset,
|
||||||
|
int32 _sample_count)
|
||||||
|
{
|
||||||
|
ASSERT(sizeof(float) == sizeof(uint32));
|
||||||
|
register const char * src = (const char *) _src;
|
||||||
|
register char * dst = (char *) _dst;
|
||||||
|
register int32 sample_count = _sample_count;
|
||||||
|
register int32 dst_sample_offset = _dst_sample_offset;
|
||||||
|
register int32 src_sample_offset = _src_sample_offset;
|
||||||
|
while (sample_count--) {
|
||||||
|
*(uint32 *)dst = *(const uint32 *)src;
|
||||||
|
src += src_sample_offset;
|
||||||
|
dst += dst_sample_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
|
#include <math.h>
|
||||||
|
|
||||||
void string_for_channel_mask(char *str, uint32 mask);
|
void string_for_channel_mask(char *str, uint32 mask);
|
||||||
void fix_multiaudio_format(media_multi_audio_format *format);
|
void fix_multiaudio_format(media_multi_audio_format *format);
|
||||||
|
|
||||||
|
int count_nonzero_bits(uint32 value);
|
||||||
|
|
||||||
#define PRINT_CHANNEL_MASK(fmt) do { char s[200]; string_for_channel_mask(s, (fmt).u.raw_audio.channel_mask); printf(" channel_mask 0x%08X %s\n", (fmt).u.raw_audio.channel_mask, s); } while (0)
|
#define PRINT_CHANNEL_MASK(fmt) do { char s[200]; string_for_channel_mask(s, (fmt).u.raw_audio.channel_mask); printf(" channel_mask 0x%08X %s\n", (fmt).u.raw_audio.channel_mask, s); } while (0)
|
||||||
|
|
||||||
|
uint32 GetChannelMask(int channel, uint32 all_channel_masks);
|
||||||
|
|
||||||
|
void CopySamples(float *_dst, int32 _dst_sample_offset,
|
||||||
|
const float *_src, int32 _src_sample_offset,
|
||||||
|
int32 _sample_count);
|
||||||
|
|
||||||
|
|
||||||
|
int64 frames_for_duration(double framerate, bigtime_t duration);
|
||||||
|
|
||||||
|
inline int64 frames_for_duration(double framerate, bigtime_t duration)
|
||||||
|
{
|
||||||
|
return (int64) ceil(framerate * double(duration) / 1000000.0);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user