Work in progress:
* Cleaning up and refactoring the OpenSoundNode code to use a single coding style and be less C-like in many places. * Fixed quite a few memory leaks in OpenSoundNode. * Removed large chunks of inactive code originating from the MultiAudioNode. * Transfered some functionality into NodeInput and NodeOutput, could be more. * No functional changes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25932 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
* Based on MultiAudio media addon
|
||||
* Copyright (c) 2002, 2003 Jerome Duval ([email protected])
|
||||
*/
|
||||
#include "OpenSoundAddOn.h"
|
||||
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaAddOn.h>
|
||||
@@ -22,8 +23,8 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "OpenSoundNode.h"
|
||||
#include "OpenSoundAddOn.h"
|
||||
#include "OpenSoundDevice.h"
|
||||
#include "OpenSoundDeviceEngine.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
@@ -119,7 +120,8 @@ BMediaNode * OpenSoundAddOn::InstantiateNodeFor(
|
||||
{
|
||||
CALLED();
|
||||
|
||||
OpenSoundDevice *device = (OpenSoundDevice*)fDevices.ItemAt(info->internal_id);
|
||||
OpenSoundDevice *device = (OpenSoundDevice*)fDevices.ItemAt(
|
||||
info->internal_id);
|
||||
if (device == NULL) {
|
||||
*out_error = B_ERROR;
|
||||
return NULL;
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
#define MAX_CHANNELS 32
|
||||
#define NB_BUFFERS 32
|
||||
|
||||
//#define DEFAULT_BUFFER_SIZE 2048
|
||||
//#define DEFAULT_BUFFER_SIZE (32*1024)
|
||||
//#define DEFAULT_BUFFER_SIZE (16*1024)
|
||||
#define DEFAULT_BUFFER_SIZE (2*1024)
|
||||
#define DEFAULT_BUFFER_SIZE 2048
|
||||
|
||||
/* define to support encoded audio (AC3, MPEG, ...) when the card supports it */
|
||||
//#define ENABLE_NON_RAW_SUPPORT 1
|
||||
|
||||
@@ -93,7 +93,7 @@ status_t OpenSoundDeviceEngine::Open(int mode)
|
||||
Close();
|
||||
return EIO;
|
||||
}
|
||||
#if 0
|
||||
#if 1
|
||||
// set fragments
|
||||
v = 0x7fff0000 | 0x000b; // unlimited * 2048
|
||||
if (ioctl(fFD, SNDCTL_DSP_SETFRAGMENT, &v, sizeof(int)) < 0) {
|
||||
@@ -193,22 +193,27 @@ status_t OpenSoundDeviceEngine::UpdateInfo(void)
|
||||
}
|
||||
|
||||
|
||||
bigtime_t OpenSoundDeviceEngine::PlaybackLatency(void)
|
||||
bigtime_t
|
||||
OpenSoundDeviceEngine::PlaybackLatency()
|
||||
{
|
||||
bigtime_t latency;
|
||||
int delay;
|
||||
delay = GetODelay();
|
||||
delay = 0; //XXX
|
||||
latency = ((double)delay * 1000000LL
|
||||
/ (fMediaFormat.u.raw_audio.channel_count * fMediaFormat.u.raw_audio.frame_rate
|
||||
* (fMediaFormat.AudioFormat() & media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
||||
PRINT(("PlaybackLatency: odelay %d latency %Ld card %Ld\n", delay, latency, CardLatency()));
|
||||
delay = 0; //XXX
|
||||
latency = (bigtime_t)((double)delay * 1000000LL
|
||||
/ (fMediaFormat.u.raw_audio.channel_count
|
||||
* fMediaFormat.u.raw_audio.frame_rate
|
||||
* (fMediaFormat.AudioFormat()
|
||||
& media_raw_audio_format::B_AUDIO_SIZE_MASK)));
|
||||
PRINT(("PlaybackLatency: odelay %d latency %Ld card %Ld\n", delay, latency,
|
||||
CardLatency()));
|
||||
latency += CardLatency();
|
||||
return latency;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t OpenSoundDeviceEngine::RecordingLatency(void)
|
||||
bigtime_t
|
||||
OpenSoundDeviceEngine::RecordingLatency()
|
||||
{
|
||||
return 0LL; //XXX
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,436 +2,284 @@
|
||||
* OpenSound media addon for BeOS and Haiku
|
||||
*
|
||||
* Copyright (c) 2007, François Revol (revol@free.fr)
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Based on MultiAudio media addon
|
||||
* Copyright (c) 2002, 2003 Jerome Duval (jerome.duval@free.fr)
|
||||
*
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
#ifndef _OPENSOUNDNODE_H
|
||||
#define _OPENSOUNDNODE_H
|
||||
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaNode.h>
|
||||
#include <FileInterface.h>
|
||||
#include <BufferConsumer.h>
|
||||
#include <BufferProducer.h>
|
||||
#include <Controllable.h>
|
||||
#include <MediaEventLooper.h>
|
||||
#include <MediaNode.h>
|
||||
#include <Message.h>
|
||||
#include <ParameterWeb.h>
|
||||
#include <TimeSource.h>
|
||||
#include <Controllable.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <List.h>
|
||||
//#include "soundcard.h"
|
||||
#include "OpenSoundDevice.h"
|
||||
#include "OpenSoundDeviceEngine.h"
|
||||
#include "OpenSoundDeviceMixer.h"
|
||||
|
||||
/*bool format_is_acceptible(
|
||||
const media_format & producer_format,
|
||||
const media_format & consumer_format);*/
|
||||
|
||||
class OpenSoundNode;
|
||||
class OpenSoundDevice;
|
||||
class OpenSoundDeviceEngine;
|
||||
class OpenSoundDeviceMixer;
|
||||
|
||||
struct audio_buf_info;
|
||||
|
||||
|
||||
class OpenSoundNode : public BBufferConsumer, public BBufferProducer,
|
||||
public BTimeSource, public BMediaEventLooper, public BControllable {
|
||||
|
||||
private:
|
||||
class NodeInput;
|
||||
class NodeOutput;
|
||||
|
||||
protected:
|
||||
virtual ~OpenSoundNode();
|
||||
|
||||
public:
|
||||
explicit OpenSoundNode(BMediaAddOn* addon,
|
||||
const char* name,
|
||||
OpenSoundDevice* device,
|
||||
int32 internalID, BMessage* config);
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
// BMediaNode interface
|
||||
public:
|
||||
virtual BMediaAddOn* AddOn(int32* internalID) const;
|
||||
// Who instantiated you -- or NULL for app class
|
||||
|
||||
protected:
|
||||
virtual void Preroll();
|
||||
// These don't return errors; instead, they use the global error
|
||||
// condition reporter. A node is required to have a queue of at
|
||||
// least one pending command (plus TimeWarp) and is recommended to
|
||||
// allow for at least one pending command of each type. Allowing an
|
||||
// arbitrary number of outstanding commands might be nice, but apps
|
||||
// cannot depend on that happening.
|
||||
|
||||
public:
|
||||
virtual status_t HandleMessage(int32 message,
|
||||
const void* data, size_t size);
|
||||
|
||||
class node_input
|
||||
{
|
||||
public:
|
||||
node_input(media_input &input, media_format format);
|
||||
~node_input();
|
||||
protected:
|
||||
virtual void NodeRegistered();
|
||||
virtual status_t RequestCompleted(
|
||||
const media_request_info& info);
|
||||
virtual void SetTimeSource(BTimeSource* timeSource);
|
||||
|
||||
OpenSoundNode *fNode;
|
||||
int32 fEngineId;
|
||||
OpenSoundDeviceEngine *fRealEngine; // engine it's connected to. can be a shadow one (!= fEngineId)
|
||||
int fAFmt; // AFMT_* for this one
|
||||
int32 fChannelId;
|
||||
media_input fInput;
|
||||
media_format fPreferredFormat;
|
||||
media_format fFormat;
|
||||
// BBufferConsumer interface
|
||||
protected:
|
||||
virtual status_t AcceptFormat(
|
||||
const media_destination& dest,
|
||||
media_format* format);
|
||||
// Someone, probably the producer, is asking you about this format.
|
||||
// Give your honest opinion, possibly modifying *format. Do not ask
|
||||
// upstream producer about the format, since he's synchronously
|
||||
// waiting for your reply.
|
||||
virtual status_t GetNextInput(int32* cookie,
|
||||
media_input* out_input);
|
||||
virtual void DisposeInputCookie(int32 cookie);
|
||||
virtual void BufferReceived(BBuffer* buffer);
|
||||
virtual void ProducerDataStatus(
|
||||
const media_destination& for_whom,
|
||||
int32 status,
|
||||
bigtime_t at_performance_time);
|
||||
virtual status_t GetLatencyFor(
|
||||
const media_destination& for_whom,
|
||||
bigtime_t* out_latency,
|
||||
media_node_id* out_timesource);
|
||||
virtual status_t Connected(const media_source& producer,
|
||||
const media_destination& where,
|
||||
const media_format& with_format,
|
||||
media_input* out_input);
|
||||
// here's a good place to request buffer group usage
|
||||
|
||||
thread_id fThread;
|
||||
uint32 fBufferCycle;
|
||||
// multi_buffer_info fOldMBI;
|
||||
// BBuffer *fBuffer;
|
||||
BList fBuffers; // of (BBuffer *)
|
||||
};
|
||||
virtual void Disconnected(const media_source& producer,
|
||||
const media_destination& where);
|
||||
|
||||
class node_output
|
||||
{
|
||||
public:
|
||||
node_output(media_output &output, media_format format);
|
||||
~node_output();
|
||||
virtual status_t FormatChanged(const media_source& producer,
|
||||
const media_destination& consumer,
|
||||
int32 change_tag,
|
||||
const media_format& format);
|
||||
|
||||
OpenSoundNode *fNode;
|
||||
int32 fEngineId;
|
||||
OpenSoundDeviceEngine *fRealEngine; // engine it's connected to. can be a shadow one (!= fEngineId)
|
||||
int fAFmt; // AFMT_* for this one
|
||||
int32 fChannelId;
|
||||
media_output fOutput;
|
||||
media_format fPreferredFormat;
|
||||
media_format fFormat;
|
||||
virtual status_t SeekTagRequested(
|
||||
const media_destination& destination,
|
||||
bigtime_t in_target_time,
|
||||
uint32 in_flags,
|
||||
media_seek_tag* out_seek_tag,
|
||||
bigtime_t* out_tagged_time,
|
||||
uint32* out_flags);
|
||||
|
||||
// BBufferProducer interface
|
||||
protected:
|
||||
virtual status_t FormatSuggestionRequested(media_type type,
|
||||
int32 quality, media_format* format);
|
||||
|
||||
thread_id fThread;
|
||||
BBufferGroup *fBufferGroup;
|
||||
bool fOutputEnabled;
|
||||
uint64 fSamplesSent;
|
||||
volatile uint32 fBufferCycle;
|
||||
// multi_buffer_info fOldMBI;
|
||||
};
|
||||
virtual status_t FormatProposal(const media_source& output,
|
||||
media_format* format);
|
||||
|
||||
virtual status_t FormatChangeRequested(
|
||||
const media_source& source,
|
||||
const media_destination& destination,
|
||||
media_format* io_format,
|
||||
int32* _deprecated_);
|
||||
virtual status_t GetNextOutput(int32* cookie,
|
||||
media_output* out_output);
|
||||
virtual status_t DisposeOutputCookie(int32 cookie);
|
||||
|
||||
virtual status_t SetBufferGroup(
|
||||
const media_source& for_source,
|
||||
BBufferGroup* group);
|
||||
|
||||
virtual status_t PrepareToConnect(const media_source& what,
|
||||
const media_destination& where,
|
||||
media_format* format,
|
||||
media_source* out_source,
|
||||
char* out_name);
|
||||
|
||||
virtual void Connect(status_t error,
|
||||
const media_source& source,
|
||||
const media_destination& destination,
|
||||
const media_format& format,
|
||||
char* io_name);
|
||||
|
||||
virtual void Disconnect(const media_source& what,
|
||||
const media_destination& where);
|
||||
|
||||
virtual void LateNoticeReceived(
|
||||
const media_source& what,
|
||||
bigtime_t how_much,
|
||||
bigtime_t performance_time);
|
||||
|
||||
virtual void EnableOutput(const media_source& what,
|
||||
bool enabled, int32* _deprecated_);
|
||||
virtual void AdditionalBufferRequested(
|
||||
const media_source& source,
|
||||
media_buffer_id prev_buffer,
|
||||
bigtime_t prev_time,
|
||||
const media_seek_tag* prev_tag);
|
||||
|
||||
class OpenSoundNode :
|
||||
public BBufferConsumer,
|
||||
public BBufferProducer,
|
||||
public BTimeSource,
|
||||
public BMediaEventLooper,
|
||||
public BControllable
|
||||
{
|
||||
// BMediaEventLooper interface
|
||||
protected:
|
||||
virtual ~OpenSoundNode(void);
|
||||
|
||||
public:
|
||||
|
||||
explicit OpenSoundNode(BMediaAddOn *addon, char* name, OpenSoundDevice *device,
|
||||
int32 internal_id, BMessage * config);
|
||||
|
||||
virtual status_t InitCheck(void) const;
|
||||
|
||||
/*************************/
|
||||
/* begin from BMediaNode */
|
||||
public:
|
||||
virtual BMediaAddOn* AddOn(
|
||||
int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */
|
||||
|
||||
protected:
|
||||
/* These don't return errors; instead, they use the global error condition reporter. */
|
||||
/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
|
||||
/* and is recommended to allow for at least one pending command of each type. */
|
||||
/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
|
||||
/* cannot depend on that happening. */
|
||||
virtual void Preroll(void);
|
||||
|
||||
public:
|
||||
virtual status_t HandleMessage(
|
||||
int32 message,
|
||||
const void * data,
|
||||
size_t size);
|
||||
|
||||
protected:
|
||||
virtual void NodeRegistered(void); /* reserved 2 */
|
||||
virtual status_t RequestCompleted(const media_request_info &info);
|
||||
virtual void SetTimeSource(BTimeSource *timeSource);
|
||||
|
||||
/* end from BMediaNode */
|
||||
/***********************/
|
||||
|
||||
/******************************/
|
||||
/* begin from BBufferConsumer */
|
||||
|
||||
//included from BMediaAddOn
|
||||
//virtual status_t HandleMessage(
|
||||
// int32 message,
|
||||
// const void * data,
|
||||
// size_t size);
|
||||
|
||||
/* Someone, probably the producer, is asking you about this format. Give */
|
||||
/* your honest opinion, possibly modifying *format. Do not ask upstream */
|
||||
/* producer about the format, since he's synchronously waiting for your */
|
||||
/* reply. */
|
||||
virtual status_t AcceptFormat(
|
||||
const media_destination & dest,
|
||||
media_format * format);
|
||||
virtual status_t GetNextInput(
|
||||
int32 * cookie,
|
||||
media_input * out_input);
|
||||
virtual void DisposeInputCookie(
|
||||
int32 cookie);
|
||||
virtual void BufferReceived(
|
||||
BBuffer * buffer);
|
||||
virtual void ProducerDataStatus(
|
||||
const media_destination & for_whom,
|
||||
int32 status,
|
||||
bigtime_t at_performance_time);
|
||||
virtual status_t GetLatencyFor(
|
||||
const media_destination & for_whom,
|
||||
bigtime_t * out_latency,
|
||||
media_node_id * out_timesource);
|
||||
virtual status_t Connected(
|
||||
const media_source & producer, /* here's a good place to request buffer group usage */
|
||||
const media_destination & where,
|
||||
const media_format & with_format,
|
||||
media_input * out_input);
|
||||
virtual void Disconnected(
|
||||
const media_source & producer,
|
||||
const media_destination & where);
|
||||
/* The notification comes from the upstream producer, so he's already cool with */
|
||||
/* the format; you should not ask him about it in here. */
|
||||
virtual status_t FormatChanged(
|
||||
const media_source & producer,
|
||||
const media_destination & consumer,
|
||||
int32 change_tag,
|
||||
const media_format & format);
|
||||
|
||||
/* Given a performance time of some previous buffer, retrieve the remembered tag */
|
||||
/* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
|
||||
/* idea being that flags can be added later, and the understood flags returned in */
|
||||
/* *out_flags. */
|
||||
virtual status_t SeekTagRequested(
|
||||
const media_destination & destination,
|
||||
bigtime_t in_target_time,
|
||||
uint32 in_flags,
|
||||
media_seek_tag * out_seek_tag,
|
||||
bigtime_t * out_tagged_time,
|
||||
uint32 * out_flags);
|
||||
|
||||
/* end from BBufferConsumer */
|
||||
/****************************/
|
||||
|
||||
/******************************/
|
||||
/* begin from BBufferProducer */
|
||||
|
||||
virtual status_t FormatSuggestionRequested( media_type type,
|
||||
int32 quality,
|
||||
media_format* format);
|
||||
|
||||
virtual status_t FormatProposal( const media_source& output,
|
||||
media_format* format);
|
||||
|
||||
virtual status_t FormatChangeRequested( const media_source& source,
|
||||
const media_destination& destination,
|
||||
media_format* io_format,
|
||||
int32* _deprecated_);
|
||||
virtual status_t GetNextOutput( int32* cookie,
|
||||
media_output* out_output);
|
||||
virtual status_t DisposeOutputCookie( int32 cookie);
|
||||
|
||||
virtual status_t SetBufferGroup( const media_source& for_source,
|
||||
BBufferGroup* group);
|
||||
|
||||
virtual status_t PrepareToConnect( const media_source& what,
|
||||
const media_destination& where,
|
||||
media_format* format,
|
||||
media_source* out_source,
|
||||
char* out_name);
|
||||
|
||||
virtual void Connect( status_t error,
|
||||
const media_source& source,
|
||||
const media_destination& destination,
|
||||
const media_format& format,
|
||||
char* io_name);
|
||||
|
||||
virtual void Disconnect( const media_source& what,
|
||||
const media_destination& where);
|
||||
|
||||
virtual void LateNoticeReceived( const media_source& what,
|
||||
bigtime_t how_much,
|
||||
bigtime_t performance_time);
|
||||
|
||||
virtual void EnableOutput( const media_source & what,
|
||||
bool enabled,
|
||||
int32* _deprecated_);
|
||||
virtual void AdditionalBufferRequested( const media_source& source,
|
||||
media_buffer_id prev_buffer,
|
||||
bigtime_t prev_time,
|
||||
const media_seek_tag* prev_tag);
|
||||
|
||||
/* end from BBufferProducer */
|
||||
/****************************/
|
||||
|
||||
/*****************/
|
||||
/* BControllable */
|
||||
/*****************/
|
||||
|
||||
/********************************/
|
||||
/* start from BMediaEventLooper */
|
||||
|
||||
protected:
|
||||
/* you must override to handle your events! */
|
||||
/* you should not call HandleEvent directly */
|
||||
virtual void HandleEvent( const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
|
||||
/* end from BMediaEventLooper */
|
||||
/******************************/
|
||||
|
||||
/********************************/
|
||||
/* start from BTimeSource */
|
||||
protected:
|
||||
virtual void SetRunMode( run_mode mode);
|
||||
virtual status_t TimeSourceOp( const time_source_op_info &op,
|
||||
void *_reserved);
|
||||
|
||||
/* end from BTimeSource */
|
||||
/******************************/
|
||||
|
||||
/********************************/
|
||||
/* start from BControllable */
|
||||
protected:
|
||||
virtual status_t GetParameterValue( int32 id,
|
||||
bigtime_t* last_change,
|
||||
void* value,
|
||||
size_t* ioSize);
|
||||
virtual void SetParameterValue( int32 id,
|
||||
bigtime_t when,
|
||||
const void* value,
|
||||
size_t size);
|
||||
virtual BParameterWeb* MakeParameterWeb();
|
||||
|
||||
status_t PropagateParameterChanges(int from, int type, const char *id);
|
||||
|
||||
/* end from BControllable */
|
||||
/******************************/
|
||||
virtual void HandleEvent(const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
|
||||
// BTimeSource interface
|
||||
protected:
|
||||
virtual void SetRunMode(run_mode mode);
|
||||
virtual status_t TimeSourceOp(const time_source_op_info& op,
|
||||
void* _reserved);
|
||||
|
||||
virtual status_t HandleStart(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleSeek(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleWarp(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleStop(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleBuffer(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleDataStatus(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleParameter(
|
||||
const media_timed_event *event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
// BControllable interface
|
||||
protected:
|
||||
virtual status_t GetParameterValue(int32 id,
|
||||
bigtime_t* last_change,
|
||||
void* value, size_t* ioSize);
|
||||
virtual void SetParameterValue(int32 id,
|
||||
bigtime_t when, const void* value,
|
||||
size_t size);
|
||||
virtual BParameterWeb* MakeParameterWeb();
|
||||
|
||||
private:
|
||||
void _ProcessGroup(BParameterGroup* group,
|
||||
int32 index, int32& _parameters);
|
||||
void _ProcessMux(BDiscreteParameter* parameter,
|
||||
int32 index);
|
||||
status_t _PropagateParameterChanges(int from,
|
||||
int type, const char* id);
|
||||
|
||||
protected:
|
||||
virtual status_t HandleStart(const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleSeek(const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleWarp(const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleStop(const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleBuffer(
|
||||
const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleDataStatus(
|
||||
const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
virtual status_t HandleParameter(
|
||||
const media_timed_event* event,
|
||||
bigtime_t lateness,
|
||||
bool realTimeEvent = false);
|
||||
|
||||
public:
|
||||
static void GetFlavor(flavor_info* outInfo, int32 id);
|
||||
static void GetFormat(media_format* outFormat);
|
||||
|
||||
static void GetFlavor(flavor_info * outInfo, int32 id);
|
||||
static void GetFormat(media_format * outFormat);
|
||||
|
||||
status_t GetConfigurationFor(BMessage * into_message);
|
||||
status_t GetConfigurationFor(BMessage* intoMessage);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
OpenSoundNode( /* private unimplemented */
|
||||
const OpenSoundNode & clone);
|
||||
OpenSoundNode & operator=(
|
||||
const OpenSoundNode & clone);
|
||||
OpenSoundNode(const OpenSoundNode& clone);
|
||||
// private unimplemented
|
||||
OpenSoundNode& operator=(const OpenSoundNode& clone);
|
||||
|
||||
//void WriteBuffer( BBuffer *buffer, node_input &input );
|
||||
//void WriteZeros(node_input &input, uint32 bufferCycle);
|
||||
void WriteZeros(node_input &input, size_t len);
|
||||
void FillWithZeros(node_input &input);
|
||||
void FillNextBuffer(node_input &channel, BBuffer* buffer);
|
||||
private:
|
||||
static void _SignalHandler(int sig);
|
||||
|
||||
static int32 _run_thread_( void *data );
|
||||
int32 RunThread();
|
||||
status_t StartThread();
|
||||
status_t StopThread();
|
||||
|
||||
static void _sig_handler_(int sig);
|
||||
static int32 _engine_play_thread_( void *data );
|
||||
static int32 _engine_rec_thread_( void *data );
|
||||
int32 EnginePlayThread(node_input *input);
|
||||
int32 EngineRecThread(node_output *output);
|
||||
static int32 _PlayThreadEntry(void* data);
|
||||
static int32 _RecThreadEntry(void* data);
|
||||
int32 _PlayThread(NodeInput* input);
|
||||
int32 _RecThread(NodeOutput* output);
|
||||
|
||||
status_t StartPlayThread(node_input *input);
|
||||
status_t StopPlayThread(node_input *input);
|
||||
status_t StartRecThread(node_output *output);
|
||||
status_t StopRecThread(node_output *output);
|
||||
status_t _StartPlayThread(NodeInput* input);
|
||||
status_t _StopPlayThread(NodeInput* input);
|
||||
status_t _StartRecThread(NodeOutput* output);
|
||||
status_t _StopRecThread(NodeOutput* output);
|
||||
|
||||
void AllocateBuffers(node_output &channel);
|
||||
BBuffer* FillNextBuffer(audio_buf_info *abinfo, node_output &channel);
|
||||
// BBuffer* FillNextBuffer( multi_buffer_info &MBI,
|
||||
// node_output &channel);
|
||||
// void UpdateTimeSource(multi_buffer_info &MBI,
|
||||
// multi_buffer_info &oldMBI,
|
||||
// node_input &input);
|
||||
void UpdateTimeSource(audio_buf_info *abinfo,
|
||||
node_input &input);
|
||||
void _AllocateBuffers(NodeOutput& channel);
|
||||
BBuffer* _FillNextBuffer(audio_buf_info* abinfo,
|
||||
NodeOutput& channel);
|
||||
void _UpdateTimeSource(audio_buf_info* abinfo,
|
||||
NodeInput& input);
|
||||
|
||||
|
||||
node_output* FindOutput(media_source source);
|
||||
node_input* FindInput(media_destination dest);
|
||||
node_input* FindInput(int32 destinationId);
|
||||
NodeOutput* _FindOutput(
|
||||
const media_source& source) const;
|
||||
NodeInput* _FindInput(
|
||||
const media_destination& dest) const;
|
||||
NodeInput* _FindInput(int32 destinationId);
|
||||
|
||||
void ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters);
|
||||
void ProcessMux(BDiscreteParameter *parameter, int32 index);
|
||||
|
||||
status_t fInitCheckStatus;
|
||||
private:
|
||||
status_t fInitCheckStatus;
|
||||
|
||||
BMediaAddOn *fAddOn;
|
||||
int32 fId;
|
||||
BMediaAddOn* fAddOn;
|
||||
int32 fId;
|
||||
|
||||
BList fInputs;
|
||||
BList fInputs;
|
||||
BList fOutputs;
|
||||
|
||||
bigtime_t fLatency;
|
||||
BList fOutputs;
|
||||
#if 1
|
||||
media_format fPreferredFormat;
|
||||
// TODO: remove and use use a preferred format
|
||||
// per NodeInput/NodeOutput channel
|
||||
media_format fPreferredFormat;
|
||||
#endif
|
||||
|
||||
bigtime_t fInternalLatency;
|
||||
// this is computed from the real (negotiated) chunk size and bit rate,
|
||||
// not the defaults that are in the parameters
|
||||
bigtime_t fBufferPeriod;
|
||||
|
||||
|
||||
//volatile uint32 fBufferCycle;
|
||||
sem_id fBufferAvailableSem;
|
||||
|
||||
|
||||
thread_id fThread;
|
||||
|
||||
OpenSoundDevice *fDevice;
|
||||
|
||||
//multi_description MD;
|
||||
//multi_format_info MFI;
|
||||
//multi_buffer_list MBL;
|
||||
|
||||
//multi_mix_control_info MMCI;
|
||||
//multi_mix_control MMC[MAX_CONTROLS];
|
||||
|
||||
bool fTimeSourceStarted;
|
||||
|
||||
int64 fOldPlayedFramesCount;
|
||||
bigtime_t fOldPlayedRealTime;
|
||||
|
||||
BParameterWeb *fWeb;
|
||||
|
||||
BMessage fConfig;
|
||||
bigtime_t fLatency;
|
||||
bigtime_t fInternalLatency;
|
||||
// this is computed from the real (negotiated) chunk size
|
||||
// and bit rate, not the defaults that are in the
|
||||
// parameters
|
||||
OpenSoundDevice* fDevice;
|
||||
bool fTimeSourceStarted;
|
||||
int64 fOldPlayedFramesCount;
|
||||
bigtime_t fOldPlayedRealTime;
|
||||
BParameterWeb* fWeb;
|
||||
BMessage fConfig;
|
||||
};
|
||||
|
||||
#endif /* _OPENSOUNDNODE_H */
|
||||
#endif // _OPENSOUNDNODE_H
|
||||
|
||||
Reference in New Issue
Block a user