Author: axeld Date: 2010-04-12 22:36:19 +0200 (Mon, 12 Apr 2010) New Revision: 36199 Changeset: http://dev.haiku-os.org/changeset/36199/haiku Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioReader.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.h haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.cpp haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.h haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp haiku/trunk/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.h haiku/trunk/src/apps/mediaplayer/supplier/ProxyAudioSupplier.cpp haiku/trunk/src/apps/mediaplayer/supplier/ProxyAudioSupplier.h Log: * The AudioProducer now correctly handles late producer notices by ignoring extra notices for buffers already scheduled. * Also, the AudioSupplier/AudioReader classes now know their initial latency, and the AudioProducer is now using that one to advertize its own initial latency - this fixes late buffers on start, causing the latency to grow too large. * Cleanup here and there. Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -77,6 +77,13 @@ } +bigtime_t +AudioAdapter::InitialLatency() const +{ + return fSource->InitialLatency(); +} + + status_t AudioAdapter::Read(void* buffer, int64 pos, int64 frames) { Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioAdapter.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,8 +1,11 @@ /* - * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> + * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ +#ifndef AUDIO_ADAPTER_H +#define AUDIO_ADAPTER_H + /*! This AudioReader slaves an AudioConverter and an AudioResampler to convert the source data to a given format. At this time the number of channels cannot be changed and the output @@ -10,21 +13,22 @@ If input and output format are the same, the overhead is quit small. */ -#ifndef AUDIO_ADAPTER_H -#define AUDIO_ADAPTER_H #include "AudioReader.h" + class AudioChannelConverter; class AudioFormatConverter; class AudioResampler; + class AudioAdapter : public AudioReader { public: AudioAdapter(AudioReader* source, const media_format& format); virtual ~AudioAdapter(); + virtual bigtime_t InitialLatency() const; virtual status_t Read(void* buffer, int64 pos, int64 frames); virtual status_t InitCheck() const; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,7 +1,9 @@ /* - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ + + #include "AudioChannelConverter.h" #include <new> @@ -10,29 +12,15 @@ using std::nothrow; + //#define TRACE_AUDIO_CONVERTER #ifdef TRACE_AUDIO_CONVERTER -# define TRACE(x...) printf(x) +# define TRACE(x...) printf(x) #else -# define TRACE(x...) +# define TRACE(x...) #endif -AudioChannelConverter::AudioChannelConverter(AudioReader* source, - const media_format& format) - : AudioReader(format), - fSource(source) -{ - // TODO: check the format and make sure everything matches - // except for channel count -} - - -AudioChannelConverter::~AudioChannelConverter() -{ -} - - template<typename Type, typename BigType> static void convert(Type* inBuffer, Type* outBuffer, int32 inChannels, int32 outChannels, @@ -79,6 +67,31 @@ } +// #pragma mark - + + +AudioChannelConverter::AudioChannelConverter(AudioReader* source, + const media_format& format) + : AudioReader(format), + fSource(source) +{ + // TODO: check the format and make sure everything matches + // except for channel count +} + + +AudioChannelConverter::~AudioChannelConverter() +{ +} + + +bigtime_t +AudioChannelConverter::InitialLatency() const +{ + fSource->InitialLatency(); +} + + status_t AudioChannelConverter::Read(void* outBuffer, int64 pos, int64 frames) { Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioChannelConverter.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,24 +1,27 @@ /* - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ +#ifndef AUDIO_CHANNEL_CONVERTER_H +#define AUDIO_CHANNEL_CONVERTER_H + /*! This AudioReader just converts the source channel count into another one, e.g. 1 -> 2. Frame rate and sample format remain unchanged. */ -#ifndef AUDIO_CHANNEL_CONVERTER_H -#define AUDIO_CHANNEL_CONVERTER_H #include "AudioReader.h" + class AudioChannelConverter : public AudioReader { public: AudioChannelConverter(AudioReader* source, const media_format& format); virtual ~AudioChannelConverter(); + virtual bigtime_t InitialLatency() const; virtual status_t Read(void* buffer, int64 pos, int64 frames); virtual status_t InitCheck() const; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,9 +1,10 @@ /* - * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ + #include "AudioFormatConverter.h" #include <ByteOrder.h> @@ -12,44 +13,12 @@ //#define TRACE_AUDIO_CONVERTER #ifdef TRACE_AUDIO_CONVERTER -# define TRACE(x...) printf(x) +# define TRACE(x...) printf(x) #else -# define TRACE(x...) +# define TRACE(x...) #endif -AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format, - uint32 byte_order) - : AudioReader(), - fSource(NULL) -{ - uint32 hostByteOrder - = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; - if (source && source->Format().type == B_MEDIA_RAW_AUDIO - && source->Format().u.raw_audio.byte_order == hostByteOrder) { - fFormat = source->Format(); - fFormat.u.raw_audio.format = format; - fFormat.u.raw_audio.byte_order = byte_order; - int32 inSampleSize = source->Format().u.raw_audio.format - & media_raw_audio_format::B_AUDIO_SIZE_MASK; - int32 outSampleSize = fFormat.u.raw_audio.format - & media_raw_audio_format::B_AUDIO_SIZE_MASK; - if (inSampleSize != outSampleSize) { - fFormat.u.raw_audio.buffer_size - = source->Format().u.raw_audio.buffer_size * outSampleSize - / inSampleSize; - } - } else - source = NULL; - fSource = source; -} - - -AudioFormatConverter::~AudioFormatConverter() -{ -} - - struct ReadFloat { inline int operator()(const void* buffer) const { // 0 == mid, -1.0 == bottom, 1.0 == top @@ -150,8 +119,7 @@ } -static -void +static void swap_sample_byte_order(void* buffer, uint32 format, size_t length) { type_code type = B_ANY_TYPE; @@ -175,6 +143,48 @@ } +// #pragma mark - + + +AudioFormatConverter::AudioFormatConverter(AudioReader* source, uint32 format, + uint32 byte_order) + : + AudioReader(), + fSource(NULL) +{ + uint32 hostByteOrder + = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN; + if (source && source->Format().type == B_MEDIA_RAW_AUDIO + && source->Format().u.raw_audio.byte_order == hostByteOrder) { + fFormat = source->Format(); + fFormat.u.raw_audio.format = format; + fFormat.u.raw_audio.byte_order = byte_order; + int32 inSampleSize = source->Format().u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK; + int32 outSampleSize = fFormat.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK; + if (inSampleSize != outSampleSize) { + fFormat.u.raw_audio.buffer_size + = source->Format().u.raw_audio.buffer_size * outSampleSize + / inSampleSize; + } + } else + source = NULL; + fSource = source; +} + + +AudioFormatConverter::~AudioFormatConverter() +{ +} + + +bigtime_t +AudioFormatConverter::InitialLatency() const +{ + fSource->InitialLatency(); +} + status_t AudioFormatConverter::Read(void* buffer, int64 pos, int64 frames) { Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioFormatConverter.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,25 +1,28 @@ /* - * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ +#ifndef AUDIO_FORMAT_CONVERTER_H +#define AUDIO_FORMAT_CONVERTER_H + /*! This AudioReader just converts the source sample format (and byte order) into another one, e.g. LE short -> BE float. Frame rate and channel count remain unchanged. */ -#ifndef AUDIO_FORMAT_CONVERTER_H -#define AUDIO_FORMAT_CONVERTER_H #include "AudioReader.h" + class AudioFormatConverter : public AudioReader { public: AudioFormatConverter(AudioReader* source, uint32 format, uint32 byte_order); virtual ~AudioFormatConverter(); + virtual bigtime_t InitialLatency() const; virtual status_t Read(void* buffer, int64 pos, int64 frames); virtual status_t InitCheck() const; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -37,13 +37,13 @@ // debugging //#define TRACE_AUDIO_PRODUCER #ifdef TRACE_AUDIO_PRODUCER -# define TRACE(x...) printf(x) -# define TRACE_BUFFER(x...) -# define ERROR(x...) fprintf(stderr, x) +# define TRACE(x...) printf(x) +# define TRACE_BUFFER(x...) +# define ERROR(x...) fprintf(stderr, x) #else -# define TRACE(x...) -# define TRACE_BUFFER(x...) -# define ERROR(x...) fprintf(stderr, x) +# define TRACE(x...) +# define TRACE_BUFFER(x...) +# define ERROR(x...) fprintf(stderr, x) #endif @@ -85,24 +85,63 @@ #endif // DEBUG_TO_FILE +static bigtime_t +estimate_internal_latency(const media_format& format) +{ + bigtime_t startTime = system_time(); + // calculate the number of samples per buffer + int32 sampleSize = format.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK; + int32 sampleCount = format.u.raw_audio.buffer_size / sampleSize; + // alloc float buffers of this size + const int bufferCount = 10; // number of input buffers + float* buffers[bufferCount + 1]; + for (int32 i = 0; i < bufferCount + 1; i++) + buffers[i] = new float[sampleCount]; + float* outBuffer = buffers[bufferCount]; + // fill all buffers save the last one with arbitrary data and merge them + // into the last one + for (int32 i = 0; i < bufferCount; i++) { + for (int32 k = 0; k < sampleCount; k++) { + buffers[i][k] = ((float)i * (float)k) + / float(bufferCount * sampleCount); + } + } + for (int32 k = 0; k < sampleCount; k++) { + outBuffer[k] = 0; + for (int32 i = 0; i < bufferCount; i++) + outBuffer[k] += buffers[i][k]; + outBuffer[k] /= bufferCount; + } + // cleanup + for (int32 i = 0; i < bufferCount + 1; i++) + delete[] buffers[i]; + return system_time() - startTime; +} -// constructor + +// #pragma mark - + + AudioProducer::AudioProducer(const char* name, AudioSupplier* supplier, bool lowLatency) - : BMediaNode(name), - BBufferProducer(B_MEDIA_RAW_AUDIO), - BMediaEventLooper(), + : + BMediaNode(name), + BBufferProducer(B_MEDIA_RAW_AUDIO), + BMediaEventLooper(), - fBufferGroup(NULL), - fLatency(0), - fInternalLatency(0), - fLowLatency(lowLatency), - fOutputEnabled(true), - fFramesSent(0), - fStartTime(0), - fSupplier(supplier), + fBufferGroup(NULL), + fLatency(0), + fInternalLatency(0), + fLastLateNotice(0), + fNextScheduledBuffer(0), + fLowLatency(lowLatency), + fOutputEnabled(true), + fFramesSent(0), + fStartTime(0), + fSupplier(supplier), - fPeakListener(NULL) + fPeakListener(NULL) { TRACE("%p->AudioProducer::AudioProducer(%s, %p, %d)\n", this, name, supplier, lowLatency); @@ -135,9 +174,11 @@ // we're not connected yet fOutput.destination = media_destination::null; fOutput.format = fPreferredFormat; + // init the audio supplier - if (fSupplier) { + if (fSupplier != NULL) { fSupplier->SetAudioProducer(this); + SetInitialLatency(fSupplier->InitialLatency()); } } @@ -359,41 +400,6 @@ } -static bigtime_t -estimate_internal_latency(const media_format& format) -{ - bigtime_t startTime = system_time(); - // calculate the number of samples per buffer - int32 sampleSize = format.u.raw_audio.format - & media_raw_audio_format::B_AUDIO_SIZE_MASK; - int32 sampleCount = format.u.raw_audio.buffer_size / sampleSize; - // alloc float buffers of this size - const int bufferCount = 10; // number of input buffers - float* buffers[bufferCount + 1]; - for (int32 i = 0; i < bufferCount + 1; i++) - buffers[i] = new float[sampleCount]; - float* outBuffer = buffers[bufferCount]; - // fill all buffers save the last one with arbitrary data and merge them - // into the last one - for (int32 i = 0; i < bufferCount; i++) { - for (int32 k = 0; k < sampleCount; k++) { - buffers[i][k] = ((float)i * (float)k) - / float(bufferCount * sampleCount); - } - } - for (int32 k = 0; k < sampleCount; k++) { - outBuffer[k] = 0; - for (int32 i = 0; i < bufferCount; i++) - outBuffer[k] += buffers[i][k]; - outBuffer[k] /= bufferCount; - } - // cleanup - for (int32 i = 0; i < bufferCount + 1; i++) - delete[] buffers[i]; - return system_time() - startTime; -} - - void AudioProducer::Connect(status_t error, const media_source& source, const media_destination& destination, const media_format& format, @@ -490,6 +496,13 @@ // If we're late, we need to catch up. Respond in a manner appropriate // to our current run mode. if (what == fOutput.source) { + // Ignore the notices for buffers we already send out (or scheduled + // their event) before we processed the last notice + if (fLastLateNotice > performanceTime) + return; + + fLastLateNotice = fNextScheduledBuffer; + if (RunMode() == B_RECORDING) { // ... } else if (RunMode() == B_INCREASE_LATENCY) { @@ -595,9 +608,10 @@ TRACE("AudioProducer::HandleEvent(B_START)\n"); if (RunState() != B_STARTED) { fFramesSent = 0; - fStartTime = event->event_time; + fStartTime = event->event_time + fSupplier->InitialLatency(); printf("B_START: start time: %lld\n", fStartTime); - media_timed_event firstBufferEvent(fStartTime, + media_timed_event firstBufferEvent( + fStartTime - fSupplier->InitialLatency(), BTimedEventQueue::B_HANDLE_BUFFER); EventQueue()->AddEvent(firstBufferEvent); } @@ -607,7 +621,7 @@ case BTimedEventQueue::B_STOP: TRACE("AudioProducer::HandleEvent(B_STOP)\n"); EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, - BTimedEventQueue::B_HANDLE_BUFFER); + BTimedEventQueue::B_HANDLE_BUFFER); TRACE("AudioProducer::HandleEvent(B_STOP) done\n"); break; @@ -633,10 +647,10 @@ / (sampleSize * fOutput.format.u.raw_audio.channel_count); fFramesSent += nFrames; - bigtime_t nextEvent = fStartTime + fNextScheduledBuffer = fStartTime + bigtime_t(double(fFramesSent) * 1000000.0 - / double(fOutput.format.u.raw_audio.frame_rate)); - media_timed_event nextBufferEvent(nextEvent, + / double(fOutput.format.u.raw_audio.frame_rate)); + media_timed_event nextBufferEvent(fNextScheduledBuffer, BTimedEventQueue::B_HANDLE_BUFFER); EventQueue()->AddEvent(nextBufferEvent); } else { @@ -663,7 +677,8 @@ { TRACE("AudioProducer::ChangeFormat()\n"); - format->u.raw_audio.buffer_size = media_raw_audio_format::wildcard.buffer_size; + format->u.raw_audio.buffer_size + = media_raw_audio_format::wildcard.buffer_size; status_t ret = _SpecializeFormat(format); if (ret != B_OK) { @@ -677,7 +692,8 @@ return ret; } - ret = BBufferProducer::ChangeFormat(fOutput.source, fOutput.destination, format); + ret = BBufferProducer::ChangeFormat(fOutput.source, fOutput.destination, + format); if (ret != B_OK) { TRACE(" ChangeFormat(): %s\n", strerror(ret)); return ret; @@ -707,20 +723,20 @@ } if (format->u.raw_audio.channel_count - == media_raw_audio_format::wildcard.channel_count) { + == media_raw_audio_format::wildcard.channel_count) { format->u.raw_audio.channel_count = 2; TRACE(" -> adjusting channel count, it was wildcard\n"); } if (format->u.raw_audio.frame_rate - == media_raw_audio_format::wildcard.frame_rate) { + == media_raw_audio_format::wildcard.frame_rate) { format->u.raw_audio.frame_rate = 44100.0; TRACE(" -> adjusting frame rate, it was wildcard\n"); } // check the buffer size, which may still be wildcarded if (format->u.raw_audio.buffer_size - == media_raw_audio_format::wildcard.buffer_size) { + == media_raw_audio_format::wildcard.buffer_size) { // pick something comfortable to suggest TRACE(" -> adjusting buffer size, it was wildcard\n"); @@ -734,7 +750,6 @@ if (!fLowLatency) format->u.raw_audio.buffer_size *= 3; - } return B_OK; @@ -794,9 +809,9 @@ // number of sample in the buffer // fill in the buffer header - media_header* hdr = buffer->Header(); - hdr->type = B_MEDIA_RAW_AUDIO; - hdr->time_source = TimeSource()->ID(); + media_header* header = buffer->Header(); + header->type = B_MEDIA_RAW_AUDIO; + header->time_source = TimeSource()->ID(); buffer->SetSizeUsed(fOutput.format.u.raw_audio.buffer_size); bigtime_t performanceTime = bigtime_t(double(fFramesSent) @@ -817,9 +832,9 @@ // stamp buffer if (RunMode() == B_RECORDING) { - hdr->start_time = eventTime; + header->start_time = eventTime; } else { - hdr->start_time = fStartTime + performanceTime; + header->start_time = fStartTime + performanceTime; } #if DEBUG_TO_FILE Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioProducer.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -8,10 +8,11 @@ #ifndef AUDIO_PRODUCER_H #define AUDIO_PRODUCER_H + #include <BufferProducer.h> -//#include <Controllable.h> #include <MediaEventLooper.h> + class AudioSupplier; class BHandler; @@ -19,6 +20,7 @@ MSG_PEAK_NOTIFICATION = 'pknt' }; + class AudioProducer : public BBufferProducer, public BMediaEventLooper { public: AudioProducer(const char* name, @@ -116,6 +118,8 @@ bool fUsingOurBuffers; bigtime_t fLatency; bigtime_t fInternalLatency; + bigtime_t fLastLateNotice; + bigtime_t fNextScheduledBuffer; bool fLowLatency; media_output fOutput; bool fOutputEnabled; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioReader.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioReader.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioReader.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -18,6 +18,7 @@ void SetFormat(const media_format& format); const media_format& Format() const; + virtual bigtime_t InitialLatency() const = 0; virtual status_t Read(void* buffer, int64 pos, int64 frames) = 0; void SetOutOffset(int64 offset); Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,7 +1,9 @@ /* - * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> + * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ + + #include "AudioResampler.h" #include <stdio.h> @@ -11,39 +13,12 @@ //#define TRACE_AUDIO_RESAMPLER #ifdef TRACE_AUDIO_RESAMPLER -# define TRACE(x...) printf(x) +# define TRACE(x...) printf(x) #else -# define TRACE(x...) +# define TRACE(x...) #endif -AudioResampler::AudioResampler() - : AudioReader(), - fSource(NULL), - fTimeScale(1.0), - fInOffset(0) -{ -} - - -AudioResampler::AudioResampler(AudioReader* source, float frameRate, - float timeScale) - : AudioReader(), - fSource(NULL), - fTimeScale(timeScale), - fInOffset(0) -{ - SetSource(source); - if (fSource) - fFormat.u.raw_audio.frame_rate = frameRate; -} - - -AudioResampler::~AudioResampler() -{ -} - - //! Calculates the greatest common divider of /a/ and /b/. template<typename T> inline T @@ -92,6 +67,45 @@ } +// #pragma mark - + + +AudioResampler::AudioResampler() + : + AudioReader(), + fSource(NULL), + fTimeScale(1.0), + fInOffset(0) +{ +} + + +AudioResampler::AudioResampler(AudioReader* source, float frameRate, + float timeScale) + : + AudioReader(), + fSource(NULL), + fTimeScale(timeScale), + fInOffset(0) +{ + SetSource(source); + if (fSource) + fFormat.u.raw_audio.frame_rate = frameRate; +} + + +AudioResampler::~AudioResampler() +{ +} + + +bigtime_t +AudioResampler::InitialLatency() const +{ + return fSource->InitialLatency(); +} + + status_t AudioResampler::Read(void* buffer, int64 pos, int64 frames) { @@ -185,7 +199,7 @@ TRACE("AudioResampler::SetSource() - NULL source\n"); return; } - + if (source->Format().type != B_MEDIA_RAW_AUDIO) { TRACE("AudioResampler::SetSource() - not B_MEDIA_RAW_AUDIO\n"); return; @@ -197,7 +211,7 @@ TRACE("AudioResampler::SetSource() - not host byte order\n"); return; } - + float frameRate = FrameRate(); // don't overwrite previous audio frame rate fSource = source; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioResampler.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,19 +1,21 @@ /* - * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> + * Copyright 2000-2006 Ingo Weinhold <ingo_weinhold@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ +#ifndef AUDIO_RESAMPLER_H +#define AUDIO_RESAMPLER_H + /*! This AudioReader does both resampling an audio source to a different sample rate and rescaling the time, e.g. it is possible to convert the source data from 41.1 KHz to 96 KHz played backward twice as fast (time scale = -2). */ -#ifndef AUDIO_RESAMPLER_H -#define AUDIO_RESAMPLER_H #include "AudioReader.h" + class AudioResampler : public AudioReader { public: AudioResampler(); @@ -21,6 +23,7 @@ float frameRate, float timeScale = 1.0); virtual ~AudioResampler(); + virtual bigtime_t InitialLatency() const; virtual status_t Read(void* buffer, int64 pos, int64 frames); virtual status_t InitCheck() const; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,6 +1,8 @@ -/* Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>, +/* Copyright 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>, * All Rights Reserved. Distributed under the terms of the MIT license. */ + + #include "AudioSupplier.h" #include "AudioProducer.h" @@ -26,6 +28,6 @@ status_t AudioSupplier::InitCheck() const { - return (fAudioProducer ? B_OK : B_NO_INIT); + return fAudioProducer ? B_OK : B_NO_INIT; } Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioSupplier.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,11 +1,12 @@ -/* Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>, +/* Copyright 2000-2008, Ingo Weinhold <ingo_weinhold@xxxxxx>, * All Rights Reserved. Distributed under the terms of the MIT license. */ +#ifndef AUDIO_SUPPLIER_H +#define AUDIO_SUPPLIER_H + /*! This class is an interface used by the AudioProducer to retreive the audio data to be played. */ -#ifndef AUDIO_SUPPLIER_H -#define AUDIO_SUPPLIER_H #include <MediaDefs.h> @@ -14,21 +15,23 @@ class AudioProducer; class AudioSupplier { - public: +public: AudioSupplier(); virtual ~AudioSupplier(); virtual void SetAudioProducer(AudioProducer* producer); + virtual status_t InitCheck() const; + + virtual bigtime_t InitialLatency() const = 0; + virtual status_t GetFrames(void* buffer, int64 frameCount, bigtime_t startTime, bigtime_t endTime) = 0; virtual void SetFormat(const media_format& format) = 0; - virtual status_t InitCheck() const; - - protected: +protected: AudioProducer* fAudioProducer; }; Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.cpp 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.cpp 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,8 +1,9 @@ /* - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> * All rights reserved. Distributed under the terms of the MIT licensce. */ + #include "AudioVolumeConverter.h" #include <stdio.h> @@ -13,31 +14,12 @@ //#define TRACE_AUDIO_CONVERTER #ifdef TRACE_AUDIO_CONVERTER -# define TRACE(x...) printf(x) +# define TRACE(x...) printf(x) #else -# define TRACE(x...) +# define TRACE(x...) #endif -AudioVolumeConverter::AudioVolumeConverter(AudioReader* source, float volume) - : AudioReader(), - fSource(NULL), - fVolume(volume), - fPreviousVolume(volume) -{ - if (source && source->Format().type == B_MEDIA_RAW_AUDIO) - fFormat = source->Format(); - else - source = NULL; - fSource = source; -} - - -AudioVolumeConverter::~AudioVolumeConverter() -{ -} - - template<typename SampleType> static void convert(SampleType* buffer, const int32 samples, const float volume, @@ -66,6 +48,36 @@ } +// #pragma mark - + + +AudioVolumeConverter::AudioVolumeConverter(AudioReader* source, float volume) + : + AudioReader(), + fSource(NULL), + fVolume(volume), + fPreviousVolume(volume) +{ + if (source && source->Format().type == B_MEDIA_RAW_AUDIO) + fFormat = source->Format(); + else + source = NULL; + fSource = source; +} + + +AudioVolumeConverter::~AudioVolumeConverter() +{ +} + + +bigtime_t +AudioVolumeConverter::InitialLatency() const +{ + return fSource->InitialLatency(); +} + + status_t AudioVolumeConverter::Read(void* buffer, int64 pos, int64 frames) { Modified: haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.h 2010-04-12 20:34:04 UTC (rev 36198) +++ haiku/trunk/src/apps/mediaplayer/media_node_framework/audio/AudioVolumeConverter.h 2010-04-12 20:36:19 UTC (rev 36199) @@ -1,23 +1,26 @@ /* - * Copyright © 2008 Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2008 Stephan Aßmus <superstippi@xxxxxx> [... truncated: 272 lines follow ...]