From 683cf2ff58b85b9224cd8a7e08310c2b1041b952 Mon Sep 17 00:00:00 2001 From: Hamish Morrison Date: Fri, 9 Jan 2015 20:56:32 +0000 Subject: [PATCH] BMediaRecorder: fix a few issues, fix style, remove unused SoundUtils * Use the preferred time source (GetTimeSource) for the node * Fix node releasing when creating the connection fails * Add virtual slots and padding * Refactor _Connect method --- headers/private/media/MediaRecorder.h | 87 +++++---- headers/private/media/MediaRecorderNode.h | 22 +-- headers/private/media/SoundUtils.h | 56 ------ src/apps/soundrecorder/RecorderWindow.cpp | 8 +- src/apps/soundrecorder/RecorderWindow.h | 2 +- src/kits/media/Jamfile | 3 +- src/kits/media/MediaRecorder.cpp | 227 +++++++++------------- src/kits/media/MediaRecorderNode.cpp | 14 +- src/kits/media/SoundUtils.cpp | 107 ---------- 9 files changed, 164 insertions(+), 362 deletions(-) delete mode 100644 headers/private/media/SoundUtils.h delete mode 100644 src/kits/media/SoundUtils.cpp diff --git a/headers/private/media/MediaRecorder.h b/headers/private/media/MediaRecorder.h index 8b6d54ec3f..417be03f1d 100644 --- a/headers/private/media/MediaRecorder.h +++ b/headers/private/media/MediaRecorder.h @@ -6,16 +6,31 @@ #define _MEDIA_RECORDER_H +#include #include -#include - -#include "MediaRecorderNode.h" -#include "SoundUtils.h" namespace BPrivate { namespace media { + +class BMediaRecorderNode; + class BMediaRecorder { +public: + enum notification { + B_WILL_START = 1, // performance_time + B_WILL_STOP, // performance_time immediate + B_WILL_SEEK, // performance_time media_time + B_WILL_TIMEWARP, // real_time performance_time + }; + + typedef void (*ProcessFunc)(void* cookie, + bigtime_t timestamp, void* data, + size_t size, const media_format& format); + + typedef void (*NotifyFunc)(void* cookie, + notification what, ...); + public: BMediaRecorder(const char* name, media_type type @@ -25,14 +40,6 @@ public: status_t InitCheck() const; - typedef void (*ProcessFunc)(void* cookie, - bigtime_t timestamp, void* data, - size_t datasize, - const media_format& format); - - typedef void (*NotifyFunc)(void* cookie, - int32 code, ...); - status_t SetHooks(ProcessFunc recordFunc = NULL, NotifyFunc notifyFunc = NULL, void* cookie = NULL); @@ -43,17 +50,14 @@ public: virtual status_t Start(bool force = false); virtual status_t Stop(bool force = false); - virtual status_t Connect(const media_format& format, - uint32 flags = 0); + virtual status_t Connect(const media_format& format); virtual status_t Connect(const dormant_node_info& dormantInfo, - const media_format* format = NULL, - uint32 flags = 0); + const media_format& format); virtual status_t Connect(const media_node& node, - const media_output* useOutput = NULL, - const media_format* format = NULL, - uint32 flags = 0); + const media_output* output = NULL, + const media_format* format = NULL); virtual status_t Disconnect(); @@ -67,37 +71,42 @@ public: protected: - virtual void BufferReceived(void* buffer, - size_t size, + virtual void BufferReceived(void* buffer, size_t size, const media_header& header); private: - status_t _Connect( - const media_format* format, - uint32 flags, - const dormant_node_info* dormantNode, - const media_node* mediaNode, - const media_output* output); + status_t _Connect(const media_node& mediaNode, + const media_output* output, + const media_format& format); - status_t fInitErr; + virtual void _ReservedMediaRecorder0(); + virtual void _ReservedMediaRecorder1(); + virtual void _ReservedMediaRecorder2(); + virtual void _ReservedMediaRecorder3(); + virtual void _ReservedMediaRecorder4(); + virtual void _ReservedMediaRecorder5(); + virtual void _ReservedMediaRecorder6(); + virtual void _ReservedMediaRecorder7(); - bool fConnected; - bool fRunning; + status_t fInitErr; - BTimeSource* fTimeSource; + bool fConnected; + bool fRunning; + bool fReleaseOutputNode; - ProcessFunc fRecordHook; - NotifyFunc fNotifyHook; + ProcessFunc fRecordHook; + NotifyFunc fNotifyHook; - media_node fOutputNode; - media_output fOutput; + media_node fOutputNode; + media_output fOutput; - BMediaRecorderNode* fNode; - media_input fInput; + BMediaRecorderNode* fNode; + media_input fInput; - void* fBufferCookie; + void* fBufferCookie; + uint32 fPadding[32]; - friend class BMediaRecorderNode; + friend class BMediaRecorderNode; }; } diff --git a/headers/private/media/MediaRecorderNode.h b/headers/private/media/MediaRecorderNode.h index b1e421e03c..8a4f2fedfd 100644 --- a/headers/private/media/MediaRecorderNode.h +++ b/headers/private/media/MediaRecorderNode.h @@ -1,6 +1,6 @@ /* - * Copyright 1999, Be Incorporated * Copyright 2014, Dario Casalinuovo + * Copyright 1999, Be Incorporated * All Rights Reserved. * This file may be used under the terms of the Be Sample Code License. */ @@ -76,27 +76,23 @@ protected: virtual void BufferReceived(BBuffer* buffer); virtual void ProducerDataStatus( - const media_destination& forWhom, + const media_destination& destination, int32 status, bigtime_t performanceTime); - virtual status_t GetLatencyFor( - const media_destination& forWhom, - bigtime_t* outLatency, - media_node_id* outTimesource); + virtual status_t GetLatencyFor(const media_destination& destination, + bigtime_t* outLatency, + media_node_id* outTimesource); - virtual status_t Connected( - const media_source& producer, + virtual status_t Connected(const media_source& producer, const media_destination& where, - const media_format& withFormat, + const media_format& format, media_input* outInput); - virtual void Disconnected( - const media_source& producer, + virtual void Disconnected(const media_source& producer, const media_destination& where); - virtual status_t FormatChanged( - const media_source& producer, + virtual status_t FormatChanged(const media_source& producer, const media_destination& consumer, int32 tag, const media_format& format); diff --git a/headers/private/media/SoundUtils.h b/headers/private/media/SoundUtils.h deleted file mode 100644 index c9e5ec86a9..0000000000 --- a/headers/private/media/SoundUtils.h +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* -/ -/ File: SoundUtils.h -/ -/ Description: Utility functions for handling audio data. -/ -/ Copyright 1998-1999, Be Incorporated, All Rights Reserved -/ -*******************************************************************************/ - -#if ! defined( _SoundUtils_h ) -#define _SoundUtils_h - -#include - -// Simple helper functions that come in handy when doing -// buffer calculations. -double us_to_s(bigtime_t usecs); -bigtime_t s_to_us(double secs); - -int bytes_per_frame(const media_raw_audio_format & format); -int frames_per_buffer(const media_raw_audio_format & format); -bigtime_t buffer_duration(const media_raw_audio_format & format); -bigtime_t frames_duration(const media_raw_audio_format & format, - int64 num_frames); -int64 frames_for_duration(const media_raw_audio_format & format, - bigtime_t duration); -int buffers_for_duration(const media_raw_audio_format & format, - bigtime_t duration); - -// This is a common hook function interface for -// SoundConsumer and SoundProducer to use. -typedef void (*SoundProcessFunc)(void * cookie, - bigtime_t timestamp, void * data, size_t datasize, - const media_raw_audio_format & format); -typedef void (*SoundNotifyFunc)(void * cookie, - int32 code, ...); - -// These are special codes that we use in the Notify -// function hook. -enum { - B_WILL_START = 1, // performance_time - B_WILL_STOP, // performance_time immediate - B_WILL_SEEK, // performance_time media_time - B_WILL_TIMEWARP, // real_time performance_time - B_CONNECTED, // name (char*) - B_DISCONNECTED, // - B_FORMAT_CHANGED, // media_raw_audio_format* - B_NODE_DIES, // node will die! - B_HOOKS_CHANGED, // - B_OP_TIMED_OUT, // timeout that expired -- Consumer only - B_PRODUCER_DATA_STATUS, // status performance_time -- Consumer only - B_LATE_NOTICE // how_much performance_time -- Producer only -}; - -#endif /* _SoundUtils_h */ diff --git a/src/apps/soundrecorder/RecorderWindow.cpp b/src/apps/soundrecorder/RecorderWindow.cpp index a4dbf8a6cf..3868b753b2 100644 --- a/src/apps/soundrecorder/RecorderWindow.cpp +++ b/src/apps/soundrecorder/RecorderWindow.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2005, Jérôme Duval. All rights reserved. * Copyright 2014, Dario Casalinuovo. All rights reserved. + * Copyright 2005, Jérôme Duval. All rights reserved. * Distributed under the terms of the MIT License. * * Inspired by SoundCapture from Be newsletter (Media Kit Basics: @@ -43,7 +43,6 @@ #include #include -#include "SoundUtils.h" #include "RecorderWindow.h" #include "FileUtils.h" @@ -1224,9 +1223,10 @@ RecorderWindow::RecordFile(void* cookie, bigtime_t timestamp, void -RecorderWindow::NotifyRecordFile(void * cookie, int32 code, ...) +RecorderWindow::NotifyRecordFile(void * cookie, + BMediaRecorder::notification code, ...) { - if ((code == B_WILL_STOP) || (code == B_NODE_DIES)) { + if (code == BMediaRecorder::B_WILL_STOP) { RecorderWindow * window = (RecorderWindow *)cookie; // Tell the window we've stopped, if it doesn't // already know. diff --git a/src/apps/soundrecorder/RecorderWindow.h b/src/apps/soundrecorder/RecorderWindow.h index d3e3087b63..d0c405ed8a 100644 --- a/src/apps/soundrecorder/RecorderWindow.h +++ b/src/apps/soundrecorder/RecorderWindow.h @@ -168,7 +168,7 @@ private: void ErrorAlert(const char * action, status_t err); static void RecordFile(void * cookie, bigtime_t timestamp, void * data, size_t size, const media_format & format); -static void NotifyRecordFile(void * cookie, int32 code, ...); +static void NotifyRecordFile(void * cookie, BMediaRecorder::notification code, ...); static void PlayFile(void * cookie, void * data, size_t size, const media_raw_audio_format & format); static void NotifyPlayFile(void * cookie, BSoundPlayer::sound_player_notification code, ...); diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index 583b12bd68..c1e1a87c3b 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -20,7 +20,6 @@ for architectureObject in [ MultiArchSubDirSetup ] { # Private Media Kit !missing_symbols.cpp MediaRecorder.cpp - MediaRecorderNode.cpp # Public Media Kit Buffer.cpp @@ -58,6 +57,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { DefaultMediaTheme.cpp DormantNodeManager.cpp FormatManager.cpp + MediaRecorderNode.cpp Notifications.cpp request_data.cpp SharedBufferList.cpp @@ -66,7 +66,6 @@ for architectureObject in [ MultiArchSubDirSetup ] { TimeSourceObject.cpp TimeSourceObjectManager.cpp SoundPlayNode.cpp - SoundUtils.cpp # Old (R3) Media Kit (built only for GCC2) OldAudioModule.cpp diff --git a/src/kits/media/MediaRecorder.cpp b/src/kits/media/MediaRecorder.cpp index 9c929094f2..d2d6be449e 100644 --- a/src/kits/media/MediaRecorder.cpp +++ b/src/kits/media/MediaRecorder.cpp @@ -1,51 +1,20 @@ /* - * Copyright 1999, Be Incorporated + * Copyright 2015, Hamish Morrison * Copyright 2014, Dario Casalinuovo + * Copyright 1999, Be Incorporated * All Rights Reserved. * This file may be used under the terms of the Be Sample Code License. */ -#include "MediaRecorder.h" +#include #include #include #include -#include "MediaDebug.h" -#include "MediaRecorderNode.h" - - -class MediaNodeReleaser { -public: - MediaNodeReleaser(media_node& mediaNode, - bool release = true) - : - fNode(mediaNode), - fRelease(release) - { - } - - ~MediaNodeReleaser() - { - if (fRelease) - BMediaRoster::Roster()->ReleaseNode(fNode); - } - - void SetTo(media_node& node) - { - fNode = node; - } - - void SetRelease(bool release) - { - fRelease = release; - } - -private: - media_node& fNode; - bool fRelease; -}; +#include +#include BMediaRecorder::BMediaRecorder(const char* name, media_type type) @@ -53,7 +22,7 @@ BMediaRecorder::BMediaRecorder(const char* name, media_type type) fInitErr(B_OK), fConnected(false), fRunning(false), - fTimeSource(NULL), + fReleaseOutputNode(false), fRecordHook(NULL), fNotifyHook(NULL), fNode(NULL), @@ -64,7 +33,10 @@ BMediaRecorder::BMediaRecorder(const char* name, media_type type) BMediaRoster::Roster(&fInitErr); if (fInitErr == B_OK) { - fNode = new BMediaRecorderNode(name, this, type); + fNode = new(std::nothrow) BMediaRecorderNode(name, this, type); + if (fNode == NULL) + fInitErr = B_NO_MEMORY; + fInitErr = BMediaRoster::CurrentRoster()->RegisterNode(fNode); } } @@ -79,10 +51,6 @@ BMediaRecorder::~BMediaRecorder() Disconnect(); fNode->Release(); } - - if (fTimeSource != NULL) - fTimeSource->Release(); - } @@ -132,7 +100,7 @@ BMediaRecorder::BufferReceived(void* buffer, size_t size, status_t -BMediaRecorder::Connect(const media_format& format, uint32 flags) +BMediaRecorder::Connect(const media_format& format) { CALLED(); @@ -142,13 +110,42 @@ BMediaRecorder::Connect(const media_format& format, uint32 flags) if (fConnected) return B_MEDIA_ALREADY_CONNECTED; - return _Connect(&format, flags, NULL, NULL, NULL); + status_t err = B_OK; + media_node node; + + switch (format.type) { + // switch on format for default + case B_MEDIA_RAW_AUDIO: + err = BMediaRoster::Roster()->GetAudioMixer(&node); + break; + case B_MEDIA_RAW_VIDEO: + case B_MEDIA_ENCODED_VIDEO: + err = BMediaRoster::Roster()->GetVideoInput(&node); + break; + // give up? + default: + return B_MEDIA_BAD_FORMAT; + } + + if (err != B_OK) + return err; + + fReleaseOutputNode = true; + + err = _Connect(node, NULL, format); + + if (err != B_OK) { + BMediaRoster::Roster()->ReleaseNode(node); + fReleaseOutputNode = false; + } + + return err; } status_t -BMediaRecorder::Connect(const dormant_node_info& dormantInfo, - const media_format* format, uint32 flags) +BMediaRecorder::Connect(const dormant_node_info& dormantNode, + const media_format& format) { CALLED(); @@ -158,14 +155,29 @@ BMediaRecorder::Connect(const dormant_node_info& dormantInfo, if (fConnected) return B_MEDIA_ALREADY_CONNECTED; - return _Connect(format, flags, &dormantInfo, NULL, NULL); + media_node node; + status_t err = BMediaRoster::Roster()->InstantiateDormantNode(dormantNode, + &node, B_FLAVOR_IS_GLOBAL); + + if (err != B_OK) + return err; + + fReleaseOutputNode = true; + + err = _Connect(node, NULL, format); + + if (err != B_OK) { + BMediaRoster::Roster()->ReleaseNode(node); + fReleaseOutputNode = false; + } + + return err; } status_t BMediaRecorder::Connect(const media_node& node, - const media_output* useOutput, const media_format* format, - uint32 flags) + const media_output* output, const media_format* format) { CALLED(); @@ -175,7 +187,10 @@ BMediaRecorder::Connect(const media_node& node, if (fConnected) return B_MEDIA_ALREADY_CONNECTED; - return _Connect(format, flags, NULL, &node, useOutput); + if (format == NULL && output != NULL) + format = &output->format; + + return _Connect(node, output, *format); } @@ -206,11 +221,9 @@ BMediaRecorder::Disconnect() fOutputNode.node, fOutput.source, fNode->Node().node, fInput.destination); - BMediaRoster::Roster()->ReleaseNode(fOutputNode); - - if (fTimeSource != NULL) { - fTimeSource->Release(); - fTimeSource = NULL; + if (fReleaseOutputNode) { + BMediaRoster::Roster()->ReleaseNode(fOutputNode); + fReleaseOutputNode = false; } fConnected = false; @@ -240,12 +253,12 @@ BMediaRecorder::Start(bool force) // start node here status_t err = B_OK; - if (fNode->Node().kind & B_TIME_SOURCE) + if ((fOutputNode.kind & B_TIME_SOURCE) != 0) err = BMediaRoster::CurrentRoster()->StartTimeSource( fOutputNode, BTimeSource::RealTime()); else err = BMediaRoster::CurrentRoster()->StartNode( - fOutputNode, fTimeSource->Now()); + fOutputNode, fNode->TimeSource()->Now()); // then un-mute it if (err == B_OK) { @@ -327,99 +340,42 @@ BMediaRecorder::Format() const status_t -BMediaRecorder::_Connect(const media_format* format, - uint32 flags, const dormant_node_info* dormantNode, - const media_node* mediaNode, const media_output* output) +BMediaRecorder::_Connect(const media_node& node, + const media_output* output, const media_format& format) { CALLED(); status_t err = B_OK; - media_format ourFormat; - media_node node; - MediaNodeReleaser away(node, false); + media_format ourFormat = format; media_output ourOutput; - // argument checking and set-up - if (format != NULL) - ourFormat = *format; - if (fNode == NULL) return B_ERROR; - if (mediaNode == NULL && output != NULL) - return B_MISMATCHED_VALUES; - - if (dormantNode != NULL && (mediaNode != NULL || output != NULL)) - return B_MISMATCHED_VALUES; - - if (format == NULL && output != NULL) - ourFormat = output->format; - fNode->SetAcceptedFormat(ourFormat); - // figure out the node to instantiate - if (dormantNode != NULL) { - - err = BMediaRoster::Roster()->InstantiateDormantNode( - *dormantNode, &node, B_FLAVOR_IS_GLOBAL); - - away.SetRelease(true); - - } else if (mediaNode != NULL) { - node = *mediaNode; - } else { - switch (ourFormat.type) { - - // switch on format for default - case B_MEDIA_RAW_AUDIO: - err = BMediaRoster::Roster()->GetAudioInput(&node); - away.SetRelease(true); - break; - - case B_MEDIA_RAW_VIDEO: - case B_MEDIA_ENCODED_VIDEO: - err = BMediaRoster::Roster()->GetVideoInput(&node); - away.SetRelease(true); - break; - - // give up? - default: - return B_MEDIA_BAD_FORMAT; - break; - } - } - fOutputNode = node; // figure out the output provided - if (output != NULL) { ourOutput = *output; } else if (err == B_OK) { - media_output outputs[10]; int32 count = 10; - err = BMediaRoster::Roster()->GetFreeOutputsFor(node, + err = BMediaRoster::Roster()->GetFreeOutputsFor(fOutputNode, outputs, count, &count, ourFormat.type); if (err != B_OK) return err; - err = B_MEDIA_BAD_SOURCE; - for (int i = 0; i < count; i++) { if (format_is_compatible(outputs[i].format, ourFormat)) { ourOutput = outputs[i]; - err = B_OK; ourFormat = outputs[i].format; break; } - } - - } else { - return err; } if (ourOutput.source == media_source::null) @@ -427,30 +383,26 @@ BMediaRecorder::_Connect(const media_format* format, // find our Node's free input media_input ourInput; - err = fNode->GetInput(&ourInput); if (err != B_OK) return err; - media_node time_source; - if (node.kind & B_TIME_SOURCE) - time_source = node; + media_node timeSource; + if ((node.kind & B_TIME_SOURCE) != 0) + timeSource = node; else - BMediaRoster::Roster()->GetSystemTimeSource(&time_source); + BMediaRoster::Roster()->GetTimeSource(&timeSource); // set time source - BMediaRoster::Roster()->SetTimeSourceFor( - fNode->Node().node, time_source.node); - - fTimeSource = BMediaRoster::CurrentRoster()->MakeTimeSourceFor( - fNode->Node()); + err = BMediaRoster::Roster()->SetTimeSourceFor(fNode->Node().node, + timeSource.node); if (err != B_OK) return err; // start the recorder node (it's always running) - err = BMediaRoster::CurrentRoster()->StartNode( - fOutputNode, fTimeSource->Now()); + err = BMediaRoster::CurrentRoster()->StartNode(fOutputNode, + fNode->TimeSource()->Now()); if (err != B_OK) return err; @@ -467,7 +419,16 @@ BMediaRecorder::_Connect(const media_format* format, return err; fConnected = true; - away.SetRelease(false); - - return err; + return B_OK; } + + +void BMediaRecorder::_ReservedMediaRecorder0() { } +void BMediaRecorder::_ReservedMediaRecorder1() { } +void BMediaRecorder::_ReservedMediaRecorder2() { } +void BMediaRecorder::_ReservedMediaRecorder3() { } +void BMediaRecorder::_ReservedMediaRecorder4() { } +void BMediaRecorder::_ReservedMediaRecorder5() { } +void BMediaRecorder::_ReservedMediaRecorder6() { } +void BMediaRecorder::_ReservedMediaRecorder7() { } + diff --git a/src/kits/media/MediaRecorderNode.cpp b/src/kits/media/MediaRecorderNode.cpp index b8c3f97caa..bb6d5beff7 100644 --- a/src/kits/media/MediaRecorderNode.cpp +++ b/src/kits/media/MediaRecorderNode.cpp @@ -1,6 +1,6 @@ /* - * Copyright 1999, Be Incorporated * Copyright 2014, Dario Casalinuovo + * Copyright 1999, Be Incorporated * All Rights Reserved. * This file may be used under the terms of the Be Sample Code License. */ @@ -13,8 +13,8 @@ #include #include -#include "MediaDebug.h" -#include "MediaRecorder.h" +#include +#include BMediaRecorderNode::BMediaRecorderNode(const char* name, @@ -146,7 +146,7 @@ BMediaRecorderNode::Start(bigtime_t performanceTime) if (fRecorder->fNotifyHook) (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, - B_WILL_START, performanceTime); + BMediaRecorder::B_WILL_START, performanceTime); fRecorder->fRunning = true; } @@ -159,7 +159,7 @@ BMediaRecorderNode::Stop(bigtime_t performanceTime, bool immediate) if (fRecorder->fNotifyHook) (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, - B_WILL_STOP, performanceTime, immediate); + BMediaRecorder::B_WILL_STOP, performanceTime, immediate); fRecorder->fRunning = false; } @@ -172,7 +172,7 @@ BMediaRecorderNode::Seek(bigtime_t mediaTime, bigtime_t performanceTime) if (fRecorder->fNotifyHook) (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, - B_WILL_SEEK, performanceTime, mediaTime); + BMediaRecorder::B_WILL_SEEK, performanceTime, mediaTime); } @@ -185,7 +185,7 @@ BMediaRecorderNode::TimeWarp(bigtime_t realTime, bigtime_t performanceTime) // at them, so we can ignore the time warp as a consumer. if (fRecorder->fNotifyHook) (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, - B_WILL_TIMEWARP, realTime, performanceTime); + BMediaRecorder::B_WILL_TIMEWARP, realTime, performanceTime); } diff --git a/src/kits/media/SoundUtils.cpp b/src/kits/media/SoundUtils.cpp deleted file mode 100644 index 26908bc81c..0000000000 --- a/src/kits/media/SoundUtils.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/****************************************************************************** -/ -/ File: SoundUtils.cpp -/ -/ Description: Utility functions for handling audio data. -/ -/ Copyright 1998-1999, Be Incorporated, All Rights Reserved -/ -******************************************************************************/ - -#include -#include "SoundUtils.h" - -// These two conversions seem to pop up all the time in media code. -// I guess it's the curse of microsecond resolution... ;-) -double -us_to_s(bigtime_t usecs) -{ - return (usecs / 1000000.0); -} - -bigtime_t -s_to_us(double secs) -{ - return (bigtime_t) (secs * 1000000.0); -} - -int -bytes_per_frame( - const media_raw_audio_format & format) -{ - // The media_raw_audio_format format constants encode the - // bytes-per-sample value in the low nybble. Having a fixed - // number of bytes-per-sample, and no inter-sample relationships, - // is what makes a format "raw". - int bytesPerSample = format.format & 0xf; - return bytesPerSample * format.channel_count; -} - -int -frames_per_buffer( - const media_raw_audio_format & format) -{ - // This will give us the number of full-sized frames that will fit - // in a buffer. (Remember, integer division automatically rounds - // down.) - int frames = 0; - if (bytes_per_frame(format) > 0) { - frames = format.buffer_size / bytes_per_frame(format); - } - return frames; -} - -bigtime_t -buffer_duration( - const media_raw_audio_format & format) -{ - // Figuring out duration is easy. We take extra precaution to - // not divide by zero or return irrelevant results. - bigtime_t duration = 0; - if (format.buffer_size > 0 && format.frame_rate > 0 - && bytes_per_frame(format) > 0) { - // In these kinds of calculations, it's always useful to double-check - // the unit conversions. (Anyone remember high school physics?) - // bytes/(bytes/frame) / frames/sec - // = frames * sec/frames - // = secs which is what we want. - duration = s_to_us((format.buffer_size / bytes_per_frame(format)) - / format.frame_rate); - } - return duration; -} - -bigtime_t -frames_duration( - const media_raw_audio_format & format, int64 num_frames) -{ - // Tells us how long in us it will take to produce num_frames, - // with the given format. - bigtime_t duration = 0; - if (format.frame_rate > 0) { - duration = s_to_us(num_frames/format.frame_rate); - } - return duration; -} - -int -buffers_for_duration( - const media_raw_audio_format & format, bigtime_t duration) -{ - // Double-checking those unit conversions again: - // secs * ( (frames/sec) / (frames/buffer) ) = secs * (buffers/sec) - // = buffers - int buffers = 0; - if (frames_per_buffer(format) > 0) { - buffers = (int) ceil(us_to_s(duration) - *(format.frame_rate/frames_per_buffer(format))); - } - return buffers; -} - -int64 -frames_for_duration( - const media_raw_audio_format & format, bigtime_t duration) -{ - return (int64) ceil(format.frame_rate*us_to_s(duration)); -}