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
This commit is contained in:
parent
739fd34cf5
commit
683cf2ff58
@ -6,16 +6,31 @@
|
||||
#define _MEDIA_RECORDER_H
|
||||
|
||||
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaNode.h>
|
||||
#include <TimeSource.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 <MediaDefs.h>
|
||||
|
||||
// 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 */
|
@ -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 <TimeSource.h>
|
||||
#include <NodeInfo.h>
|
||||
|
||||
#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.
|
||||
|
@ -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, ...);
|
||||
|
@ -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
|
||||
|
@ -1,51 +1,20 @@
|
||||
/*
|
||||
* Copyright 1999, Be Incorporated
|
||||
* Copyright 2015, Hamish Morrison <hamishm53@gmail.com>
|
||||
* 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 <MediaRecorder.h>
|
||||
|
||||
#include <MediaAddOn.h>
|
||||
#include <MediaRoster.h>
|
||||
#include <TimeSource.h>
|
||||
|
||||
#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 <MediaDebug.h>
|
||||
#include <MediaRecorderNode.h>
|
||||
|
||||
|
||||
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() { }
|
||||
|
||||
|
@ -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 <TimedEventQueue.h>
|
||||
#include <TimeSource.h>
|
||||
|
||||
#include "MediaDebug.h"
|
||||
#include "MediaRecorder.h"
|
||||
#include <MediaDebug.h>
|
||||
#include <MediaRecorder.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,107 +0,0 @@
|
||||
/******************************************************************************
|
||||
/
|
||||
/ File: SoundUtils.cpp
|
||||
/
|
||||
/ Description: Utility functions for handling audio data.
|
||||
/
|
||||
/ Copyright 1998-1999, Be Incorporated, All Rights Reserved
|
||||
/
|
||||
******************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#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));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user