* Minor cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30074 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002 David Shipman,
|
||||
* Copyright 2003-2007 Marcus Overhagen
|
||||
* Copyright 2007 Haiku Inc. All rights reserved.
|
||||
* Copyright 2007-2009 Haiku Inc. All rights reserved.
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "AudioMixer.h"
|
||||
#include "MixerCore.h"
|
||||
#include "MixerInput.h"
|
||||
@@ -31,29 +33,69 @@
|
||||
|
||||
#define USE_MEDIA_FORMAT_WORKAROUND 1
|
||||
|
||||
#define DB_TO_GAIN(db) dB_to_Gain((db))
|
||||
#define GAIN_TO_DB(gain) Gain_to_dB((gain))
|
||||
#define PERCENT_TO_GAIN(pct) ((pct) / 100.0)
|
||||
#define GAIN_TO_PERCENT(gain) ((gain) * 100.0)
|
||||
|
||||
// the id is encoded with 16 bits
|
||||
// then chan and src (or dst) are encoded with 6 bits
|
||||
// the unique number with 4 bits
|
||||
// the PARAM_ETC etc is encoded with 26 bits
|
||||
#define PARAM_SRC_ENABLE(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x1)
|
||||
#define PARAM_SRC_GAIN(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x2)
|
||||
#define PARAM_DST_ENABLE(id, chan, dst) (((id) << 16) | ((chan) << 10) | ((dst) << 4) | 0x3)
|
||||
#define PARAM_ETC(etc) (((etc) << 16) | 0x4)
|
||||
#define PARAM_SRC_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x5)
|
||||
#define PARAM_DST_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x6)
|
||||
#define PARAM_MUTE(id) (((id) << 16) | 0x7)
|
||||
#define PARAM_GAIN(id) (((id) << 16) | 0x8)
|
||||
#define PARAM_BALANCE(id) (((id) << 16) | 0x9)
|
||||
#define PARAM_STR1(id) (((id) << 16) | ((1) << 10) | 0xa)
|
||||
#define PARAM_STR2(id) (((id) << 16) | ((2) << 10) | 0xa)
|
||||
#define PARAM_STR3(id) (((id) << 16) | ((3) << 10) | 0xa)
|
||||
#define PARAM_STR4(id) (((id) << 16) | ((4) << 10) | 0xa)
|
||||
#define PARAM_STR5(id) (((id) << 16) | ((5) << 10) | 0xa)
|
||||
#define PARAM_STR6(id) (((id) << 16) | ((6) << 10) | 0xa)
|
||||
#define PARAM_STR7(id) (((id) << 16) | ((7) << 10) | 0xa)
|
||||
|
||||
#define PARAM(id) ((id) >> 16)
|
||||
#define ETC(id) ((id) >> 16)
|
||||
#define PARAM_CHAN(id) (((id) >> 10) & 0x3f)
|
||||
#define PARAM_SRC(id) (((id) >> 4) & 0x3f)
|
||||
#define PARAM_DST(id) (((id) >> 4) & 0x3f)
|
||||
#define PARAM_IS_SRC_ENABLE(id) (((id) & 0xf) == 0x1)
|
||||
#define PARAM_IS_SRC_GAIN(id) (((id) & 0xf) == 0x2)
|
||||
#define PARAM_IS_DST_ENABLE(id) (((id) & 0xf) == 0x3)
|
||||
#define PARAM_IS_ETC(id) (((id) & 0xf) == 0x4)
|
||||
#define PARAM_IS_MUTE(id) (((id) & 0xf) == 0x7)
|
||||
#define PARAM_IS_GAIN(id) (((id) & 0xf) == 0x8)
|
||||
#define PARAM_IS_BALANCE(id) (((id) & 0xf) == 0x9)
|
||||
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
static void
|
||||
multi_audio_format_specialize(media_multi_audio_format *format,
|
||||
const media_multi_audio_format *other);
|
||||
const media_multi_audio_format *other);
|
||||
#endif
|
||||
|
||||
#define FORMAT_USER_DATA_TYPE 0x7294a8f3
|
||||
#define FORMAT_USER_DATA_MAGIC_1 0xc84173bd
|
||||
#define FORMAT_USER_DATA_MAGIC_2 0x4af62b7d
|
||||
|
||||
|
||||
AudioMixer::AudioMixer(BMediaAddOn *addOn, bool isSystemMixer)
|
||||
: BMediaNode("Audio Mixer"),
|
||||
BBufferConsumer(B_MEDIA_RAW_AUDIO),
|
||||
BBufferProducer(B_MEDIA_RAW_AUDIO),
|
||||
BControllable(),
|
||||
BMediaEventLooper(),
|
||||
fAddOn(addOn),
|
||||
fCore(new MixerCore(this)),
|
||||
fWeb(0),
|
||||
fBufferGroup(0),
|
||||
fDownstreamLatency(1),
|
||||
fInternalLatency(1),
|
||||
fDisableStop(false)
|
||||
: BMediaNode("Audio Mixer"),
|
||||
BBufferConsumer(B_MEDIA_RAW_AUDIO),
|
||||
BBufferProducer(B_MEDIA_RAW_AUDIO),
|
||||
BControllable(),
|
||||
BMediaEventLooper(),
|
||||
fAddOn(addOn),
|
||||
fCore(new MixerCore(this)),
|
||||
fWeb(0),
|
||||
fBufferGroup(0),
|
||||
fDownstreamLatency(1),
|
||||
fInternalLatency(1),
|
||||
fDisableStop(false)
|
||||
{
|
||||
BMediaNode::AddNodeKind(B_SYSTEM_MIXER);
|
||||
|
||||
@@ -83,6 +125,7 @@ AudioMixer::AudioMixer(BMediaAddOn *addOn, bool isSystemMixer)
|
||||
ApplySettings();
|
||||
}
|
||||
|
||||
|
||||
AudioMixer::~AudioMixer()
|
||||
{
|
||||
BMediaEventLooper::Quit();
|
||||
@@ -102,6 +145,7 @@ AudioMixer::~AudioMixer()
|
||||
DEBUG_ONLY(fCore = 0; fBufferGroup = 0; fWeb = 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::ApplySettings()
|
||||
{
|
||||
@@ -110,17 +154,19 @@ AudioMixer::ApplySettings()
|
||||
fCore->Unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::DisableNodeStop()
|
||||
{
|
||||
fDisableStop = true;
|
||||
}
|
||||
|
||||
//
|
||||
// BMediaNode methods
|
||||
//
|
||||
|
||||
void AudioMixer::Stop(bigtime_t performance_time, bool immediate)
|
||||
// #pragma mark - BMediaNode methods
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::Stop(bigtime_t performance_time, bool immediate)
|
||||
{
|
||||
if (fDisableStop) {
|
||||
TRACE("AudioMixer STOP is disabled\n");
|
||||
@@ -130,16 +176,17 @@ void AudioMixer::Stop(bigtime_t performance_time, bool immediate)
|
||||
}
|
||||
}
|
||||
|
||||
BMediaAddOn *
|
||||
|
||||
BMediaAddOn*
|
||||
AudioMixer::AddOn(int32 *internal_id) const
|
||||
{
|
||||
*internal_id = 0;
|
||||
return fAddOn;
|
||||
}
|
||||
|
||||
//
|
||||
// BBufferConsumer methods
|
||||
//
|
||||
|
||||
// #pragma mark - BBufferConsumer methods
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::HandleMessage(int32 message, const void *data, size_t size)
|
||||
@@ -148,6 +195,7 @@ AudioMixer::HandleMessage(int32 message, const void *data, size_t size)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::AcceptFormat(const media_destination &dest, media_format *ioFormat)
|
||||
{
|
||||
@@ -187,6 +235,7 @@ AudioMixer::AcceptFormat(const media_destination &dest, media_format *ioFormat)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::GetNextInput(int32 *cookie, media_input *out_input)
|
||||
{
|
||||
@@ -219,12 +268,14 @@ AudioMixer::GetNextInput(int32 *cookie, media_input *out_input)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::DisposeInputCookie(int32 cookie)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::BufferReceived(BBuffer *buffer)
|
||||
{
|
||||
@@ -248,9 +299,8 @@ AudioMixer::BufferReceived(BBuffer *buffer)
|
||||
// to receive the buffer at the right time,
|
||||
// push it through the event looper
|
||||
media_timed_event event(buffer->Header()->start_time,
|
||||
BTimedEventQueue::B_HANDLE_BUFFER,
|
||||
buffer,
|
||||
BTimedEventQueue::B_RECYCLE_BUFFER);
|
||||
BTimedEventQueue::B_HANDLE_BUFFER, buffer,
|
||||
BTimedEventQueue::B_RECYCLE_BUFFER);
|
||||
EventQueue()->AddEvent(event);
|
||||
}
|
||||
|
||||
@@ -289,9 +339,10 @@ AudioMixer::HandleInputBuffer(BBuffer *buffer, bigtime_t lateness)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::ProducerDataStatus( const media_destination &for_whom,
|
||||
int32 status, bigtime_t at_performance_time)
|
||||
AudioMixer::ProducerDataStatus(const media_destination& for_whom,
|
||||
int32 status, bigtime_t at_performance_time)
|
||||
{
|
||||
/*
|
||||
if (IsValidDest(for_whom))
|
||||
@@ -307,10 +358,10 @@ AudioMixer::ProducerDataStatus( const media_destination &for_whom,
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::GetLatencyFor(const media_destination &for_whom,
|
||||
bigtime_t *out_latency,
|
||||
media_node_id *out_timesource)
|
||||
bigtime_t *out_latency, media_node_id *out_timesource)
|
||||
{
|
||||
// we have multiple inputs with different IDs, but
|
||||
// the port number must match our ControlPort()
|
||||
@@ -323,15 +374,16 @@ AudioMixer::GetLatencyFor(const media_destination &for_whom,
|
||||
*out_timesource = TimeSource()->ID();
|
||||
|
||||
printf("AudioMixer::GetLatencyFor %Ld, timesource is %ld\n",
|
||||
*out_latency,
|
||||
*out_timesource);
|
||||
*out_latency, *out_timesource);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::Connected(const media_source &producer, const media_destination &where,
|
||||
const media_format &with_format, media_input *out_input)
|
||||
AudioMixer::Connected(const media_source &producer,
|
||||
const media_destination &where, const media_format &with_format,
|
||||
media_input *out_input)
|
||||
{
|
||||
PRINT_FORMAT("AudioMixer::Connected: ", with_format);
|
||||
|
||||
@@ -339,11 +391,11 @@ AudioMixer::Connected(const media_source &producer, const media_destination &whe
|
||||
// BBufferProducer::PrepareToConnect() should have removed all wildcards.
|
||||
if (out_input->format.u.raw_audio.frame_rate == 0) {
|
||||
fprintf(stderr, "Audio Mixer Warning: "
|
||||
"Producer (port %ld, id %ld) connected with frame_rate=0\n",
|
||||
producer.port,
|
||||
producer.id);
|
||||
"Producer (port %ld, id %ld) connected with frame_rate=0\n",
|
||||
producer.port, producer.id);
|
||||
MixerOutput *output = fCore->Output();
|
||||
float frame_rate = output ? output->MediaOutput().format.u.raw_audio.frame_rate : 44100.0f;
|
||||
float frame_rate = output
|
||||
? output->MediaOutput().format.u.raw_audio.frame_rate : 44100.0f;
|
||||
out_input->format.u.raw_audio.frame_rate = frame_rate;
|
||||
}
|
||||
|
||||
@@ -359,8 +411,9 @@ AudioMixer::Connected(const media_source &producer, const media_destination &whe
|
||||
// we assign a new id (!= 0) to the newly created input
|
||||
out_input->destination.id = fCore->CreateInputID();
|
||||
|
||||
// We need to make sure that the outInput's name field contains a valid name,
|
||||
// the name given the connection by the producer may still be an empty string.
|
||||
// We need to make sure that the outInput's name field contains a valid
|
||||
// name, the name given the connection by the producer may still be an
|
||||
// empty string.
|
||||
// if the input has no name, assign one
|
||||
if (strlen(out_input->name) == 0)
|
||||
sprintf(out_input->name, "Input %ld", out_input->destination.id);
|
||||
@@ -373,8 +426,9 @@ AudioMixer::Connected(const media_source &producer, const media_destination &whe
|
||||
|
||||
fCore->Unlock();
|
||||
|
||||
// If we want the producer to use a specific BBufferGroup, we now need to call
|
||||
// BMediaRoster::SetOutputBuffersFor() here to set the producer's buffer group.
|
||||
// If we want the producer to use a specific BBufferGroup, we now need
|
||||
// to call BMediaRoster::SetOutputBuffersFor() here to set the producer's
|
||||
// buffer group.
|
||||
// But we have no special buffer requirements anyway...
|
||||
|
||||
UpdateParameterWeb();
|
||||
@@ -382,8 +436,10 @@ AudioMixer::Connected(const media_source &producer, const media_destination &whe
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::Disconnected(const media_source &producer, const media_destination &where)
|
||||
AudioMixer::Disconnected(const media_source &producer,
|
||||
const media_destination &where)
|
||||
{
|
||||
// One of our inputs has been disconnected
|
||||
|
||||
@@ -403,9 +459,11 @@ AudioMixer::Disconnected(const media_source &producer, const media_destination &
|
||||
UpdateParameterWeb();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::FormatChanged(const media_source &producer, const media_destination &consumer,
|
||||
int32 change_tag, const media_format &format)
|
||||
AudioMixer::FormatChanged(const media_source &producer,
|
||||
const media_destination &consumer, int32 change_tag,
|
||||
const media_format &format)
|
||||
{
|
||||
// at some point in the future (indicated by change_tag and RequestCompleted()),
|
||||
// we will receive buffers in a different format
|
||||
@@ -430,12 +488,13 @@ AudioMixer::FormatChanged(const media_source &producer, const media_destination
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// BBufferProducer methods
|
||||
//
|
||||
|
||||
// #pragma mark - BBufferProducer methods
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::FormatSuggestionRequested(media_type type, int32 quality, media_format *format)
|
||||
AudioMixer::FormatSuggestionRequested(media_type type, int32 quality,
|
||||
media_format *format)
|
||||
{
|
||||
TRACE("AudioMixer::FormatSuggestionRequested\n");
|
||||
|
||||
@@ -451,6 +510,7 @@ AudioMixer::FormatSuggestionRequested(media_type type, int32 quality, media_form
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::FormatProposal(const media_source &output, media_format *ioFormat)
|
||||
{
|
||||
@@ -476,14 +536,16 @@ AudioMixer::FormatProposal(const media_source &output, media_format *ioFormat)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// If the format isn't good, put a good format into *io_format and return error
|
||||
// If format has wildcard, specialize to what you can do (and change).
|
||||
// If you can change the format, return OK.
|
||||
// The request comes from your destination sychronously, so you cannot ask it
|
||||
// whether it likes it -- you should assume it will since it asked.
|
||||
/*! If the format isn't good, put a good format into *io_format and return error
|
||||
If format has wildcard, specialize to what you can do (and change).
|
||||
If you can change the format, return OK.
|
||||
The request comes from your destination sychronously, so you cannot ask it
|
||||
whether it likes it -- you should assume it will since it asked.
|
||||
*/
|
||||
status_t
|
||||
AudioMixer::FormatChangeRequested(const media_source &source, const media_destination &destination,
|
||||
media_format *io_format, int32 *_deprecated_)
|
||||
AudioMixer::FormatChangeRequested(const media_source &source,
|
||||
const media_destination &destination, media_format *io_format,
|
||||
int32 *_deprecated_)
|
||||
{
|
||||
// the downstream consumer node (soundcard) requested that we produce
|
||||
// another format, we need to check if the format is acceptable and
|
||||
@@ -508,25 +570,30 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
|
||||
goto err;
|
||||
}
|
||||
if (destination != output->MediaOutput().destination) {
|
||||
ERROR("AudioMixer::FormatChangeRequested: wrong output destination (port %ld, id %ld), our is (port %ld, id %ld)\n", destination.port, destination.id, output->MediaOutput().destination.port, output->MediaOutput().destination.id);
|
||||
if (destination.port == output->MediaOutput().destination.port && destination.id == output->MediaOutput().destination.id + 1) {
|
||||
ERROR("AudioMixer::FormatChangeRequested: this might be the broken R5 multi audio add-on\n");
|
||||
goto err;
|
||||
} else {
|
||||
goto err;
|
||||
ERROR("AudioMixer::FormatChangeRequested: wrong output destination "
|
||||
"(port %ld, id %ld), our is (port %ld, id %ld)\n", destination.port,
|
||||
destination.id, output->MediaOutput().destination.port,
|
||||
output->MediaOutput().destination.id);
|
||||
if (destination.port == output->MediaOutput().destination.port
|
||||
&& destination.id == output->MediaOutput().destination.id + 1) {
|
||||
ERROR("AudioMixer::FormatChangeRequested: this might be the broken "
|
||||
"R5 multi audio add-on\n");
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
if (io_format->type != B_MEDIA_RAW_AUDIO && io_format->type != B_MEDIA_UNKNOWN_TYPE) {
|
||||
if (io_format->type != B_MEDIA_RAW_AUDIO
|
||||
&& io_format->type != B_MEDIA_UNKNOWN_TYPE) {
|
||||
ERROR("AudioMixer::FormatChangeRequested: wrong format type\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* remove wildcards */
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
multi_audio_format_specialize(&io_format->u.raw_audio, &fDefaultFormat.u.raw_audio);
|
||||
#else
|
||||
io_format->SpecializeTo(&fDefaultFormat);
|
||||
#endif
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
multi_audio_format_specialize(&io_format->u.raw_audio,
|
||||
&fDefaultFormat.u.raw_audio);
|
||||
#else
|
||||
io_format->SpecializeTo(&fDefaultFormat);
|
||||
#endif
|
||||
|
||||
media_node_id id;
|
||||
FindLatencyFor(destination, &fDownstreamLatency, &id);
|
||||
@@ -537,7 +604,8 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
|
||||
TRACE("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration());
|
||||
|
||||
// Our internal latency is at least the length of a full output buffer
|
||||
fInternalLatency = BufferDuration() + max(4500LL, bigtime_t(0.5 * BufferDuration()));
|
||||
fInternalLatency = BufferDuration()
|
||||
+ max(4500LL, bigtime_t(0.5 * BufferDuration()));
|
||||
TRACE("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency);
|
||||
|
||||
SetEventLatency(fDownstreamLatency + fInternalLatency);
|
||||
@@ -545,7 +613,8 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
|
||||
// we need to inform all connected *inputs* about *our* change in latency
|
||||
PublishEventLatencyChange();
|
||||
|
||||
// XXX we might need to create more buffers, to span a larger downstream latency
|
||||
// TODO: we might need to create more buffers, to span a larger downstream
|
||||
// latency
|
||||
|
||||
// apply latency change
|
||||
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
|
||||
@@ -565,6 +634,7 @@ err:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::GetNextOutput(int32 *cookie, media_output *out_output)
|
||||
{
|
||||
@@ -592,6 +662,7 @@ AudioMixer::GetNextOutput(int32 *cookie, media_output *out_output)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::DisposeOutputCookie(int32 cookie)
|
||||
{
|
||||
@@ -599,8 +670,10 @@ AudioMixer::DisposeOutputCookie(int32 cookie)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::SetBufferGroup(const media_source &for_source, BBufferGroup *newGroup)
|
||||
AudioMixer::SetBufferGroup(const media_source &for_source,
|
||||
BBufferGroup *newGroup)
|
||||
{
|
||||
PRINT("AudioMixer::SetBufferGroup\n");
|
||||
// the downstream consumer (soundcard) node asks us to use another
|
||||
@@ -624,6 +697,7 @@ AudioMixer::SetBufferGroup(const media_source &for_source, BBufferGroup *newGrou
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AudioMixer::GetLatency(bigtime_t *out_latency)
|
||||
{
|
||||
@@ -635,17 +709,20 @@ AudioMixer::GetLatency(bigtime_t *out_latency)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::LatencyChanged(const media_source & source, const media_destination & destination,
|
||||
bigtime_t new_latency, uint32 flags)
|
||||
AudioMixer::LatencyChanged(const media_source& source,
|
||||
const media_destination& destination, bigtime_t new_latency, uint32 flags)
|
||||
{
|
||||
if (source.port != ControlPort() || source.id != 0) {
|
||||
ERROR("AudioMixer::LatencyChanged: received but has wrong source %ld/%ld\n", source.port, source.id);
|
||||
ERROR("AudioMixer::LatencyChanged: received but has wrong source "
|
||||
"%ld/%ld\n", source.port, source.id);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("AudioMixer::LatencyChanged: downstream latency from %ld/%ld to %ld/%ld changed from %Ld to %Ld\n",
|
||||
source.port, source.id, destination.port, destination.id, fDownstreamLatency, new_latency);
|
||||
TRACE("AudioMixer::LatencyChanged: downstream latency from %ld/%ld to "
|
||||
"%ld/%ld changed from %Ld to %Ld\n", source.port, source.id,
|
||||
destination.port, destination.id, fDownstreamLatency, new_latency);
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
@@ -659,7 +736,8 @@ AudioMixer::LatencyChanged(const media_source & source, const media_destination
|
||||
fDownstreamLatency = new_latency;
|
||||
SetEventLatency(fDownstreamLatency + fInternalLatency);
|
||||
|
||||
// XXX we might need to create more buffers, to span a larger downstream latency
|
||||
// XXX we might need to create more buffers, to span a larger downstream
|
||||
// latency
|
||||
|
||||
fCore->Lock();
|
||||
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
|
||||
@@ -669,16 +747,15 @@ AudioMixer::LatencyChanged(const media_source & source, const media_destination
|
||||
|
||||
status_t
|
||||
AudioMixer::PrepareToConnect(const media_source &what,
|
||||
const media_destination &where,
|
||||
media_format *format,
|
||||
media_source *out_source,
|
||||
char *out_name)
|
||||
const media_destination &where, media_format *format,
|
||||
media_source *out_source, char *out_name)
|
||||
{
|
||||
TRACE("AudioMixer::PrepareToConnect\n");
|
||||
// PrepareToConnect() is the second stage of format negotiations that happens
|
||||
// inside BMediaRoster::Connect(). At this point, the consumer's AcceptFormat()
|
||||
// method has been called, and that node has potentially changed the proposed
|
||||
// format. It may also have left wildcards in the format. PrepareToConnect()
|
||||
// PrepareToConnect() is the second stage of format negotiations that
|
||||
// happens inside BMediaRoster::Connect(). At this point, the consumer's
|
||||
// AcceptFormat() method has been called, and that node has potentially
|
||||
// changed the proposed format.
|
||||
// It may also have left wildcards in the format. PrepareToConnect()
|
||||
// *must* fully specialize the format before returning!
|
||||
// we also create the new output connection and return it in out_source.
|
||||
|
||||
@@ -693,7 +770,8 @@ AudioMixer::PrepareToConnect(const media_source &what,
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
|
||||
// is the format acceptable?
|
||||
if (format->type != B_MEDIA_RAW_AUDIO && format->type != B_MEDIA_UNKNOWN_TYPE) {
|
||||
if (format->type != B_MEDIA_RAW_AUDIO
|
||||
&& format->type != B_MEDIA_UNKNOWN_TYPE) {
|
||||
PRINT_FORMAT("AudioMixer::PrepareToConnect: bad format", *format);
|
||||
return B_MEDIA_BAD_FORMAT;
|
||||
}
|
||||
@@ -732,14 +810,23 @@ AudioMixer::PrepareToConnect(const media_source &what,
|
||||
media_output out;
|
||||
media_input in;
|
||||
int32 count;
|
||||
if (B_OK == roster->GetAudioMixer(&node) && B_OK == roster->GetConnectedOutputsFor(node, &out, 1, &count) && count == 1) {
|
||||
if (roster->GetAudioMixer(&node) == B_OK
|
||||
&& roster->GetConnectedOutputsFor(node, &out, 1, &count)
|
||||
== B_OK
|
||||
&& count == 1) {
|
||||
// use mixer output format
|
||||
format->u.raw_audio.channel_count = out.format.u.raw_audio.channel_count;
|
||||
format->u.raw_audio.frame_rate = out.format.u.raw_audio.frame_rate;
|
||||
} else if (B_OK == roster->GetAudioOutput(&node) && B_OK == roster->GetAllInputsFor(node, &in, 1, &count) && count == 1) {
|
||||
format->u.raw_audio.channel_count
|
||||
= out.format.u.raw_audio.channel_count;
|
||||
format->u.raw_audio.frame_rate
|
||||
= out.format.u.raw_audio.frame_rate;
|
||||
} else if (roster->GetAudioOutput(&node) == B_OK
|
||||
&& roster->GetAllInputsFor(node, &in, 1, &count) == B_OK
|
||||
&& count == 1) {
|
||||
// use DAC input format
|
||||
format->u.raw_audio.channel_count = in.format.u.raw_audio.channel_count;
|
||||
format->u.raw_audio.frame_rate = in.format.u.raw_audio.frame_rate;
|
||||
format->u.raw_audio.channel_count
|
||||
= in.format.u.raw_audio.channel_count;
|
||||
format->u.raw_audio.frame_rate
|
||||
= in.format.u.raw_audio.frame_rate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -749,11 +836,12 @@ AudioMixer::PrepareToConnect(const media_source &what,
|
||||
strcpy(out_name, "Mixer Output");
|
||||
|
||||
/* remove wildcards */
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
multi_audio_format_specialize(&format->u.raw_audio, &fDefaultFormat.u.raw_audio);
|
||||
#else
|
||||
format->SpecializeTo(&fDefaultFormat);
|
||||
#endif
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
multi_audio_format_specialize(&format->u.raw_audio,
|
||||
&fDefaultFormat.u.raw_audio);
|
||||
#else
|
||||
format->SpecializeTo(&fDefaultFormat);
|
||||
#endif
|
||||
|
||||
PRINT_FORMAT("AudioMixer::PrepareToConnect: final format", *format);
|
||||
|
||||
@@ -772,11 +860,10 @@ AudioMixer::PrepareToConnect(const media_source &what,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::Connect(status_t error, const media_source &source,
|
||||
const media_destination &dest,
|
||||
const media_format &format,
|
||||
char *io_name)
|
||||
const media_destination &dest, const media_format &format, char *io_name)
|
||||
{
|
||||
TRACE("AudioMixer::Connect\n");
|
||||
|
||||
@@ -791,7 +878,8 @@ AudioMixer::Connect(status_t error, const media_source &source,
|
||||
|
||||
if (error != B_OK) {
|
||||
// if an error occured, remove output from core
|
||||
ERROR("AudioMixer::Connect failed with error 0x%08lX, removing connection\n", error);
|
||||
ERROR("AudioMixer::Connect failed with error 0x%08lX, removing "
|
||||
"connection\n", error);
|
||||
fCore->Lock();
|
||||
fCore->RemoveOutput();
|
||||
fCore->Unlock();
|
||||
@@ -818,7 +906,8 @@ AudioMixer::Connect(status_t error, const media_source &source,
|
||||
TRACE("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration());
|
||||
|
||||
// Our internal latency is at least the length of a full output buffer
|
||||
fInternalLatency = BufferDuration() + max(4500LL, bigtime_t(0.5 * BufferDuration()));
|
||||
fInternalLatency = BufferDuration()
|
||||
+ max(4500LL, bigtime_t(0.5 * BufferDuration()));
|
||||
TRACE("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency);
|
||||
|
||||
SetEventLatency(fDownstreamLatency + fInternalLatency);
|
||||
@@ -826,10 +915,10 @@ AudioMixer::Connect(status_t error, const media_source &source,
|
||||
// we need to inform all connected *inputs* about *our* change in latency
|
||||
PublishEventLatencyChange();
|
||||
|
||||
// Set up the buffer group for our connection, as long as nobody handed us a
|
||||
// buffer group (via SetBufferGroup()) prior to this. That can happen, for example,
|
||||
// if the consumer calls SetOutputBuffersFor() on us from within its Connected()
|
||||
// method.
|
||||
// Set up the buffer group for our connection, as long as nobody handed
|
||||
// us a buffer group (via SetBufferGroup()) prior to this. That can
|
||||
// happen, for example, if the consumer calls SetOutputBuffersFor() on
|
||||
// us from within its Connected() method.
|
||||
if (!fBufferGroup)
|
||||
fBufferGroup = CreateBufferGroup();
|
||||
|
||||
@@ -864,7 +953,10 @@ AudioMixer::Disconnect(const media_source &what, const media_destination &where)
|
||||
|
||||
// Make sure that our connection is the one being disconnected
|
||||
MixerOutput * output = fCore->Output();
|
||||
if (!output || output->MediaOutput().node != Node() || output->MediaOutput().source != what || output->MediaOutput().destination != where) {
|
||||
if (!output
|
||||
|| output->MediaOutput().node != Node()
|
||||
|| output->MediaOutput().source != what
|
||||
|| output->MediaOutput().destination != where) {
|
||||
ERROR("AudioMixer::Disconnect can't disconnect (wrong connection)\n");
|
||||
fCore->Unlock();
|
||||
return;
|
||||
@@ -891,12 +983,14 @@ AudioMixer::Disconnect(const media_source &what, const media_destination &where)
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::LateNoticeReceived(const media_source &what, bigtime_t how_much, bigtime_t performance_time)
|
||||
AudioMixer::LateNoticeReceived(const media_source &what, bigtime_t how_much,
|
||||
bigtime_t performance_time)
|
||||
{
|
||||
// We've produced some late buffers... Increase Latency
|
||||
// is the only runmode in which we can do anything about this
|
||||
|
||||
ERROR("AudioMixer::LateNoticeReceived, %Ld too late at %Ld\n", how_much, performance_time);
|
||||
ERROR("AudioMixer::LateNoticeReceived, %Ld too late at %Ld\n", how_much,
|
||||
performance_time);
|
||||
// Note: The following code is outcommented on purpose
|
||||
// and is about to be modified at a later point
|
||||
/*
|
||||
@@ -918,7 +1012,8 @@ AudioMixer::LateNoticeReceived(const media_source &what, bigtime_t how_much, big
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::EnableOutput(const media_source &what, bool enabled, int32 *_deprecated_)
|
||||
AudioMixer::EnableOutput(const media_source &what, bool enabled,
|
||||
int32 *_deprecated_)
|
||||
{
|
||||
// we only have one output
|
||||
if (what.id != 0 || what.port != ControlPort())
|
||||
@@ -930,9 +1025,8 @@ AudioMixer::EnableOutput(const media_source &what, bool enabled, int32 *_depreca
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// BMediaEventLooper methods
|
||||
//
|
||||
// #pragma mark - BMediaEventLooper methods
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::NodeRegistered()
|
||||
@@ -942,21 +1036,23 @@ AudioMixer::NodeRegistered()
|
||||
UpdateParameterWeb();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::SetTimeSource(BTimeSource * time_source)
|
||||
{
|
||||
TRACE("AudioMixer::SetTimeSource: timesource is now %ld\n", time_source->ID());
|
||||
TRACE("AudioMixer::SetTimeSource: timesource is now %ld\n",
|
||||
time_source->ID());
|
||||
fCore->Lock();
|
||||
fCore->SetTimingInfo(time_source, fDownstreamLatency);
|
||||
fCore->Unlock();
|
||||
}
|
||||
|
||||
void
|
||||
AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool realTimeEvent)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
|
||||
void
|
||||
AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness,
|
||||
bool realTimeEvent)
|
||||
{
|
||||
switch (event->type) {
|
||||
case BTimedEventQueue::B_HANDLE_BUFFER:
|
||||
{
|
||||
HandleInputBuffer((BBuffer *)event->pointer, lateness);
|
||||
@@ -978,8 +1074,10 @@ AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool
|
||||
case BTimedEventQueue::B_STOP:
|
||||
{
|
||||
TRACE("AudioMixer::HandleEvent: B_STOP\n");
|
||||
// stopped - don't process any more buffers, flush all buffers from eventqueue
|
||||
EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
|
||||
// stopped - don't process any more buffers, flush all buffers
|
||||
// from event queue
|
||||
EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true,
|
||||
BTimedEventQueue::B_HANDLE_BUFFER);
|
||||
fCore->Lock();
|
||||
fCore->Stop();
|
||||
fCore->Unlock();
|
||||
@@ -994,13 +1092,12 @@ AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// AudioMixer methods
|
||||
//
|
||||
|
||||
// #pragma mark - AudioMixer methods
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::PublishEventLatencyChange()
|
||||
@@ -1014,24 +1111,29 @@ AudioMixer::PublishEventLatencyChange()
|
||||
|
||||
MixerInput *input;
|
||||
for (int i = 0; (input = fCore->Input(i)) != 0; i++) {
|
||||
TRACE("AudioMixer::PublishEventLatencyChange: SendLatencyChange, connection %ld/%ld to %ld/%ld event latency is now %Ld\n",
|
||||
TRACE("AudioMixer::PublishEventLatencyChange: SendLatencyChange, "
|
||||
"connection %ld/%ld to %ld/%ld event latency is now %Ld\n",
|
||||
input->MediaInput().source.port, input->MediaInput().source.id,
|
||||
input->MediaInput().destination.port, input->MediaInput().destination.id,
|
||||
EventLatency());
|
||||
SendLatencyChange(input->MediaInput().source, input->MediaInput().destination, EventLatency());
|
||||
input->MediaInput().destination.port,
|
||||
input->MediaInput().destination.id, EventLatency());
|
||||
SendLatencyChange(input->MediaInput().source,
|
||||
input->MediaInput().destination, EventLatency());
|
||||
}
|
||||
|
||||
fCore->Unlock();
|
||||
}
|
||||
|
||||
BBufferGroup *
|
||||
|
||||
BBufferGroup*
|
||||
AudioMixer::CreateBufferGroup()
|
||||
{
|
||||
// allocate enough buffers to span our downstream latency
|
||||
// (plus one for rounding up), plus one extra
|
||||
int32 count = int32(fDownstreamLatency / BufferDuration()) + 2;
|
||||
|
||||
TRACE("AudioMixer::CreateBufferGroup: fDownstreamLatency %Ld, BufferDuration %Ld, buffer count = %ld\n", fDownstreamLatency, BufferDuration(), count);
|
||||
TRACE("AudioMixer::CreateBufferGroup: fDownstreamLatency %Ld, "
|
||||
"BufferDuration %Ld, buffer count = %ld\n", fDownstreamLatency,
|
||||
BufferDuration(), count);
|
||||
|
||||
if (count < 3)
|
||||
count = 3;
|
||||
@@ -1040,21 +1142,25 @@ AudioMixer::CreateBufferGroup()
|
||||
uint32 size = fCore->Output()->MediaOutput().format.u.raw_audio.buffer_size;
|
||||
fCore->Unlock();
|
||||
|
||||
TRACE("AudioMixer: allocating %ld buffers of %ld bytes each\n", count, size);
|
||||
TRACE("AudioMixer: allocating %ld buffers of %ld bytes each\n",
|
||||
count, size);
|
||||
return new BBufferGroup(size, count);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
AudioMixer::dB_to_Gain(float db)
|
||||
{
|
||||
TRACE("dB_to_Gain: dB in: %01.2f ", db);
|
||||
if (fCore->Settings()->NonLinearGainSlider()) {
|
||||
if (db > 0) {
|
||||
db = db * (pow(abs(DB_MAX), (1.0 / DB_EXPONENT_POSITIVE)) / abs(DB_MAX));
|
||||
db = db * (pow(abs(DB_MAX), (1.0 / DB_EXPONENT_POSITIVE))
|
||||
/ abs(DB_MAX));
|
||||
db = pow(db, DB_EXPONENT_POSITIVE);
|
||||
} else {
|
||||
db = -db;
|
||||
db = db * (pow(abs(DB_MIN), (1.0 / DB_EXPONENT_NEGATIVE)) / abs(DB_MIN));
|
||||
db = db * (pow(abs(DB_MIN), (1.0 / DB_EXPONENT_NEGATIVE))
|
||||
/ abs(DB_MIN));
|
||||
db = pow(db, DB_EXPONENT_NEGATIVE);
|
||||
db = -db;
|
||||
}
|
||||
@@ -1063,6 +1169,7 @@ AudioMixer::dB_to_Gain(float db)
|
||||
return pow(10.0, db / 20.0);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
AudioMixer::Gain_to_dB(float gain)
|
||||
{
|
||||
@@ -1071,59 +1178,21 @@ AudioMixer::Gain_to_dB(float gain)
|
||||
if (fCore->Settings()->NonLinearGainSlider()) {
|
||||
if (db > 0) {
|
||||
db = pow(db, (1.0 / DB_EXPONENT_POSITIVE));
|
||||
db = db * (abs(DB_MAX) / pow(abs(DB_MAX), (1.0 / DB_EXPONENT_POSITIVE)));
|
||||
db = db * (abs(DB_MAX) / pow(abs(DB_MAX),
|
||||
(1.0 / DB_EXPONENT_POSITIVE)));
|
||||
} else {
|
||||
db = -db;
|
||||
db = pow(db, (1.0 / DB_EXPONENT_NEGATIVE));
|
||||
db = db * (abs(DB_MIN) / pow(abs(DB_MIN), (1.0 / DB_EXPONENT_NEGATIVE)));
|
||||
db = db * (abs(DB_MIN) / pow(abs(DB_MIN),
|
||||
(1.0 / DB_EXPONENT_NEGATIVE)));
|
||||
db = -db;
|
||||
}
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
//
|
||||
// BControllable methods
|
||||
//
|
||||
|
||||
#define DB_TO_GAIN(db) dB_to_Gain((db))
|
||||
#define GAIN_TO_DB(gain) Gain_to_dB((gain))
|
||||
#define PERCENT_TO_GAIN(pct) ((pct) / 100.0)
|
||||
#define GAIN_TO_PERCENT(gain) ((gain) * 100.0)
|
||||
|
||||
// the id is encoded with 16 bits
|
||||
// then chan and src (or dst) are encoded with 6 bits
|
||||
// the unique number with 4 bits
|
||||
// the PARAM_ETC etc is encoded with 26 bits
|
||||
#define PARAM_SRC_ENABLE(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x1)
|
||||
#define PARAM_SRC_GAIN(id, chan, src) (((id) << 16) | ((chan) << 10) | ((src) << 4) | 0x2)
|
||||
#define PARAM_DST_ENABLE(id, chan, dst) (((id) << 16) | ((chan) << 10) | ((dst) << 4) | 0x3)
|
||||
#define PARAM_ETC(etc) (((etc) << 16) | 0x4)
|
||||
#define PARAM_SRC_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x5)
|
||||
#define PARAM_DST_STR(id, chan) (((id) << 16) | ((chan) << 10) | 0x6)
|
||||
#define PARAM_MUTE(id) (((id) << 16) | 0x7)
|
||||
#define PARAM_GAIN(id) (((id) << 16) | 0x8)
|
||||
#define PARAM_BALANCE(id) (((id) << 16) | 0x9)
|
||||
#define PARAM_STR1(id) (((id) << 16) | ((1) << 10) | 0xa)
|
||||
#define PARAM_STR2(id) (((id) << 16) | ((2) << 10) | 0xa)
|
||||
#define PARAM_STR3(id) (((id) << 16) | ((3) << 10) | 0xa)
|
||||
#define PARAM_STR4(id) (((id) << 16) | ((4) << 10) | 0xa)
|
||||
#define PARAM_STR5(id) (((id) << 16) | ((5) << 10) | 0xa)
|
||||
#define PARAM_STR6(id) (((id) << 16) | ((6) << 10) | 0xa)
|
||||
#define PARAM_STR7(id) (((id) << 16) | ((7) << 10) | 0xa)
|
||||
|
||||
#define PARAM(id) ((id) >> 16)
|
||||
#define ETC(id) ((id) >> 16)
|
||||
#define PARAM_CHAN(id) (((id) >> 10) & 0x3f)
|
||||
#define PARAM_SRC(id) (((id) >> 4) & 0x3f)
|
||||
#define PARAM_DST(id) (((id) >> 4) & 0x3f)
|
||||
#define PARAM_IS_SRC_ENABLE(id) (((id) & 0xf) == 0x1)
|
||||
#define PARAM_IS_SRC_GAIN(id) (((id) & 0xf) == 0x2)
|
||||
#define PARAM_IS_DST_ENABLE(id) (((id) & 0xf) == 0x3)
|
||||
#define PARAM_IS_ETC(id) (((id) & 0xf) == 0x4)
|
||||
#define PARAM_IS_MUTE(id) (((id) & 0xf) == 0x7)
|
||||
#define PARAM_IS_GAIN(id) (((id) & 0xf) == 0x8)
|
||||
#define PARAM_IS_BALANCE(id) (((id) & 0xf) == 0x9)
|
||||
// #pragma markß - BControllable methods
|
||||
|
||||
|
||||
status_t
|
||||
@@ -1570,7 +1639,7 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when, const void *value,
|
||||
} else {
|
||||
input->RemoveInputChannelDestination(PARAM_CHAN(id), PARAM_DST(id));
|
||||
}
|
||||
// XXX this is really annoying
|
||||
// TODO: this is really annoying
|
||||
// The slider count of the gain control needs to be changed,
|
||||
// but calling SetChannelCount(input->GetMixerChannelCount())
|
||||
// on it has no effect on remote BParameterWebs in other apps.
|
||||
@@ -1582,13 +1651,16 @@ AudioMixer::SetParameterValue(int32 id, bigtime_t when, const void *value,
|
||||
}
|
||||
fCore->Settings()->SaveConnectionSettings(input);
|
||||
}
|
||||
|
||||
BroadcastNewParameterValue(when, id, const_cast<void *>(value), size);
|
||||
|
||||
err:
|
||||
fCore->Unlock();
|
||||
if (update)
|
||||
UpdateParameterWeb();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioMixer::UpdateParameterWeb()
|
||||
{
|
||||
@@ -1673,13 +1745,18 @@ AudioMixer::UpdateParameterWeb()
|
||||
} else {
|
||||
for (int chan = 0; chan < out->GetOutputChannelCount(); chan++) {
|
||||
subgroup = group->MakeGroup("");
|
||||
subgroup->MakeNullParameter(PARAM_SRC_STR(0, chan), B_MEDIA_RAW_AUDIO,
|
||||
StringForChannelType(buf, out->GetOutputChannelType(chan)), B_GENERIC);
|
||||
subgroup->MakeNullParameter(PARAM_SRC_STR(0, chan),
|
||||
B_MEDIA_RAW_AUDIO, StringForChannelType(buf,
|
||||
out->GetOutputChannelType(chan)), B_GENERIC);
|
||||
for (int src = 0; src < MAX_CHANNEL_TYPES; src++) {
|
||||
subsubgroup = subgroup->MakeGroup("");
|
||||
subsubgroup->MakeDiscreteParameter(PARAM_SRC_ENABLE(0, chan, src), B_MEDIA_RAW_AUDIO, "", B_ENABLE);
|
||||
subsubgroup->MakeContinuousParameter(PARAM_SRC_GAIN(0, chan, src), B_MEDIA_RAW_AUDIO,
|
||||
StringForChannelType(buf, src), B_GAIN, "%", 0.0, 100.0, 0.1);
|
||||
subsubgroup->MakeDiscreteParameter(
|
||||
PARAM_SRC_ENABLE(0, chan, src), B_MEDIA_RAW_AUDIO, "",
|
||||
B_ENABLE);
|
||||
subsubgroup->MakeContinuousParameter(
|
||||
PARAM_SRC_GAIN(0, chan, src), B_MEDIA_RAW_AUDIO,
|
||||
StringForChannelType(buf, src), B_GAIN, "%", 0.0,
|
||||
100.0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1737,9 +1814,11 @@ AudioMixer::UpdateParameterWeb()
|
||||
SetParameterWeb(web);
|
||||
}
|
||||
|
||||
|
||||
#if USE_MEDIA_FORMAT_WORKAROUND
|
||||
static void
|
||||
raw_audio_format_specialize(media_raw_audio_format *format, const media_raw_audio_format *other)
|
||||
raw_audio_format_specialize(media_raw_audio_format *format,
|
||||
const media_raw_audio_format *other)
|
||||
{
|
||||
if (format->frame_rate == 0)
|
||||
format->frame_rate = other->frame_rate;
|
||||
@@ -1755,8 +1834,10 @@ raw_audio_format_specialize(media_raw_audio_format *format, const media_raw_audi
|
||||
format->frame_rate = other->frame_rate;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
multi_audio_info_specialize(media_multi_audio_info *format, const media_multi_audio_info *other)
|
||||
multi_audio_info_specialize(media_multi_audio_info *format,
|
||||
const media_multi_audio_info *other)
|
||||
{
|
||||
if (format->channel_mask == 0)
|
||||
format->channel_mask = other->channel_mask;
|
||||
@@ -1766,8 +1847,10 @@ multi_audio_info_specialize(media_multi_audio_info *format, const media_multi_au
|
||||
format->matrix_mask = other->matrix_mask;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
multi_audio_format_specialize(media_multi_audio_format *format, const media_multi_audio_format *other)
|
||||
multi_audio_format_specialize(media_multi_audio_format *format,
|
||||
const media_multi_audio_format *other)
|
||||
{
|
||||
raw_audio_format_specialize(format, other);
|
||||
multi_audio_info_specialize(format, other);
|
||||
|
||||
Reference in New Issue
Block a user