/boot/home/config/add-ons/media/legacy.media_addon

Adding the legacy (BeOS R3) sound driver interface BMediaAddOn.

Written by Jens Winkler, snapshot from 2002-06-02.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@71 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2002-07-11 00:42:58 +00:00
parent af9bf37038
commit 440b3fb4ba
9 changed files with 1118 additions and 0 deletions
@@ -0,0 +1,430 @@
#include <fcntl.h>
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>
#include <media/Buffer.h>
#include <media/BufferGroup.h>
#include <media/ParameterWeb.h>
#include <media/TimeSource.h>
#include <support/Autolock.h>
#include <support/Debug.h>
#include "driver/audio.h"
#include "driver/sound.h"
#include "LegacyAudioConsumer.h"
#include "driver_io.h"
LegacyAudioConsumer::LegacyAudioConsumer( BMediaAddOn *addon, const char *name, int32 internal_id )
: BMediaNode( name ), BBufferConsumer( B_MEDIA_RAW_AUDIO )
{
mInitStatus = B_NO_INIT;
mAddOn = addon;
mId = internal_id;
mBuffers = NULL;
mThread = -1;
mProcessingLatency = 0LL;
mRunning = false;
mConnected = false;
io_buf1 = NULL;
AddNodeKind( B_PHYSICAL_OUTPUT );
sprintf( device_name, "/dev/audio/old/%s", name );
//open the device driver for output
fd = open( device_name, O_WRONLY );
if ( fd == 0 ) {
return;
}
DRIVER_GET_PLAYBACK_PREFERRED_BUF_SIZE( &mBuffer_size, 0 );
io_buf1 = malloc( 2 * ( sizeof( audio_buffer_header ) + mBuffer_size ) );
if ( io_buf1 == NULL ) {
close( fd );
return;
}
io_buf2 = static_cast<char *>( io_buf1 ) + sizeof( audio_buffer_header ) + mBuffer_size;
static_cast<audio_buffer_header *>( io_buf1 )->reserved_1 = sizeof( audio_buffer_header ) + mBuffer_size;
static_cast<audio_buffer_header *>( io_buf2 )->reserved_1 = sizeof( audio_buffer_header ) + mBuffer_size;
mInitStatus = B_OK;
return;
}
LegacyAudioConsumer::~LegacyAudioConsumer()
{
if ( mInitStatus != B_OK ) {
return;
}
/* Clean up */
if ( mConnected ) {
Disconnected( mInput.source, mInput.destination );
}
if ( mRunning ) {
HandleStop();
}
if ( io_buf1 != NULL ) {
free( static_cast<void *>( io_buf1 ) );
}
if ( fd != 0 ) {
close( fd );
}
}
/* BMediaNode */
BMediaAddOn *
LegacyAudioConsumer::AddOn( int32 *internal_id ) const
{
if ( internal_id ) {
*internal_id = mId;
}
return mAddOn;
}
void
LegacyAudioConsumer::NodeRegistered()
{
mInput.destination.port = ControlPort();
mInput.destination.id = 0;
mInput.source = media_source::null;
mInput.format.type = B_MEDIA_RAW_AUDIO;
mInput.format.u.raw_audio.frame_rate = 44100.0;
mInput.format.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
mInput.format.u.raw_audio.channel_count = 2;
mInput.format.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
mInput.format.u.raw_audio.buffer_size = mBuffer_size;
Run();
}
status_t
LegacyAudioConsumer::HandleMessage( int32 message, const void *data, size_t size )
{
status_t err = B_OK;
if ( BBufferConsumer::HandleMessage( message, data, size ) != B_OK ) {
if ( ( err = BMediaNode::HandleMessage( message, data, size ) ) != B_OK ) {
BMediaNode::HandleBadMessage( message, data, size );
}
}
return err;
}
/* BBufferConsumer */
status_t
LegacyAudioConsumer::AcceptFormat( const media_destination &dest, media_format *format )
{
if ( format->type != B_MEDIA_RAW_AUDIO ) {
return B_MEDIA_BAD_FORMAT;
}
format->u.raw_audio.frame_rate = 44100.0;
format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
format->u.raw_audio.channel_count = 2;
format->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
format->u.raw_audio.buffer_size = mBuffer_size;
return B_OK;
}
status_t
LegacyAudioConsumer::GetNextInput( int32 *cookie, media_input *out_input )
{
if ( *cookie == 0 ) {
memcpy( out_input, &mInput , sizeof( media_input ) );
}
return B_BAD_INDEX;
}
void
LegacyAudioConsumer::BufferReceived( BBuffer *buffer )
{
if ( ! mRunning ) {
buffer->Recycle();
} else {
media_timed_event event( buffer->Header()->start_time,
BTimedEventQueue::B_HANDLE_BUFFER,
buffer,
BTimedEventQueue::B_RECYCLE_BUFFER );
EventQueue()->AddEvent( event );
}
}
void
LegacyAudioConsumer::ProducerDataStatus( const media_destination &for_whom, int32 status,
bigtime_t at_media_time )
{
}
status_t
LegacyAudioConsumer::GetLatencyFor( const media_destination &for_whom, bigtime_t *out_latency,
media_node_id *out_timesource )
{
*out_latency = mBuffer_size * 10000 / 4 / 441;
return B_OK;
}
status_t
LegacyAudioConsumer::Connected( const media_source &producer, const media_destination &where,
const media_format &with_format, media_input *out_input )
{
mInput.source = producer;
//mInput.format = with_format;
mInput.node = Node();
strcpy( mInput.name, "Legacy Audio Consumer" );
mBuffers = new BBufferGroup;
uint32 dummy_data = 0;
int32 change_tag = 1;
BBufferConsumer::SetOutputBuffersFor( producer, mDest, mBuffers, static_cast<void *>( &dummy_data ),
&change_tag, true );
mConnected = true;
return B_OK;
}
void
LegacyAudioConsumer::Disconnected( const media_source &producer, const media_destination &where )
{
if ( mConnected ) {
delete mBuffers;
mInput.source = media_source::null;
mConnected = false;
}
}
status_t
LegacyAudioConsumer::FormatChanged( const media_source &producer, const media_destination &consumer,
int32 change_tag, const media_format &format )
{
return B_OK;
}
/* BMediaEventLooper */
void
LegacyAudioConsumer::HandleEvent( const media_timed_event *event, bigtime_t lateness, bool realTimeEvent )
{
switch(event->type) {
case BTimedEventQueue::B_START:
HandleStart( event->event_time );
break;
case BTimedEventQueue::B_STOP:
HandleStop();
break;
case BTimedEventQueue::B_WARP:
HandleTimeWarp( event->bigdata );
break;
case BTimedEventQueue::B_SEEK:
HandleSeek( event->bigdata );
break;
case BTimedEventQueue::B_HANDLE_BUFFER:
HandleBuffer( static_cast<BBuffer *>( event->pointer ) );
break;
case BTimedEventQueue::B_DATA_STATUS:
case BTimedEventQueue::B_PARAMETER:
default:
break; //HandleEvent: Unhandled event
}
}
/* LegacyAudioConsumer */
void
LegacyAudioConsumer::HandleStart( bigtime_t performance_time )
{
if ( mRunning ) {
return;
}
mPerformanceTimeBase = performance_time;
//allocate buffer available semaphore
mBuffer_avail = create_sem( 0, "legacy audio out buffer avail" );
if ( mBuffer_avail < B_OK ) {
goto init_err1;
}
//allocate buffer free semaphore
mBuffer_free = create_sem( 1, "legacy audio out buffer free" );
if ( mBuffer_free < B_OK ) {
goto init_err2;
}
//allocate output completion semaphore
mBuffer_waitIO = create_sem( 1, "legacy audio out waitIO" );
if ( mBuffer_waitIO < B_OK ) {
goto init_err3;
}
//tell the driver about the playback completion semaphore
DRIVER_SET_PLAYBACK_COMPLETION_SEM( &mBuffer_waitIO, 0 );
mThread = spawn_thread( _run_thread_, "legacy audio output", B_REAL_TIME_PRIORITY, this );
if ( mThread < B_OK ) {
goto init_err4;
}
io_buf = io_buf1;
resume_thread( mThread );
mRunning = true;
return;
init_err4:
delete_sem( mBuffer_waitIO );
init_err3:
delete_sem( mBuffer_free );
init_err2:
delete_sem( mBuffer_avail );
init_err1:
return;
}
void
LegacyAudioConsumer::HandleStop()
{
if ( ! mRunning ) {
return;
}
delete_sem( mBuffer_avail );
delete_sem( mBuffer_free );
delete_sem( mBuffer_waitIO );
wait_for_thread( mThread, &mThread );
mRunning = false;
}
void
LegacyAudioConsumer::HandleTimeWarp( bigtime_t performance_time )
{
mPerformanceTimeBase = performance_time;
}
void
LegacyAudioConsumer::HandleSeek( bigtime_t performance_time )
{
mPerformanceTimeBase = performance_time;
}
void
LegacyAudioConsumer::HandleBuffer( BBuffer *buffer )
{
void *buf;
//wait for free buffer
acquire_sem( mBuffer_free );
//avoid buffer currently in use
buf = static_cast<void *>( ( io_buf == io_buf2 ) ? io_buf1 : io_buf2 );
//prepare buffer
memcpy( static_cast<char *>( buf ) + sizeof( audio_buffer_header ), buffer->Data(), buffer->SizeUsed() );
//tell the io thread a new buffer is ready
release_sem( mBuffer_avail );
}
int32
LegacyAudioConsumer::_run_thread_( void *data )
{
return static_cast<LegacyAudioConsumer *>( data )->RunThread();
}
int32
LegacyAudioConsumer::RunThread()
{
while ( 1 ) {
//wait for next buffer
if ( acquire_sem( mBuffer_avail ) == B_BAD_SEM_ID ) {
return B_OK;
}
//send buffer
DRIVER_UNSAFE_WRITE( io_buf, 0 );
//wait for IO
if ( acquire_sem( mBuffer_waitIO ) == B_BAD_SEM_ID ) {
return B_OK;
}
io_buf = ( io_buf == io_buf2 ) ? io_buf1 : io_buf2;
//mark buffer free
release_sem( mBuffer_free );
}
return B_OK;
}
@@ -0,0 +1,121 @@
#ifndef _LEGACY_AUDIO_CONSUMER_H
#define _LEGACY_AUDIO_CONSUMER_H
#include <kernel/OS.h>
#include <media/BufferConsumer.h>
#include <media/Controllable.h>
#include <media/MediaEventLooper.h>
#include <media/MediaDefs.h>
#include <media/MediaAddOn.h>
#include <media/MediaNode.h>
#include <support/Locker.h>
class LegacyAudioConsumer :
public virtual BMediaEventLooper,
public virtual BBufferConsumer
{
public:
LegacyAudioConsumer( BMediaAddOn *addon, const char *name, int32 internal_id );
~LegacyAudioConsumer();
virtual status_t InitCheck() const
{ return mInitStatus; }
/* BMediaNode */
public:
virtual BMediaAddOn *AddOn( int32 *internal_id ) const;
protected:
virtual void NodeRegistered();
virtual status_t HandleMessage( int32 message,
const void *data,
size_t size );
/* BMediaEventLooper */
protected:
virtual void HandleEvent( const media_timed_event *event,
bigtime_t lateness,
bool realTimeEvent = false );
/* BBufferConsumer */
public:
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 ) {}
protected:
virtual void BufferReceived( BBuffer *buffer );
private:
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 );
virtual void Disconnected( const media_source &producer,
const media_destination &where );
virtual status_t FormatChanged( const media_source &producer,
const media_destination &consumer,
int32 change_tag,
const media_format &format );
/* state */
private:
void HandleStart( bigtime_t performance_time );
void HandleStop();
void HandleTimeWarp( bigtime_t performance_time );
void HandleSeek( bigtime_t performance_time );
void HandleBuffer( BBuffer *buffer );
static int32 _run_thread_( void *data );
int32 RunThread();
status_t mInitStatus;
BMediaAddOn *mAddOn;
int32 mId;
char device_name[32];
BBufferGroup *mBuffers;
thread_id mThread;
/* state variables */
volatile bool mRunning;
volatile bool mConnected;
volatile bigtime_t mPerformanceTimeBase;
volatile bigtime_t mProcessingLatency;
media_input mInput;
media_destination mDest;
size_t mBuffer_size;
volatile void *io_buf1;
volatile void *io_buf2;
volatile void *io_buf;
int fd; //file descriptor for hw driver
sem_id mBuffer_avail;
sem_id mBuffer_free;
sem_id mBuffer_waitIO; //IO completion semaphore
};
#endif
@@ -0,0 +1,209 @@
#include <media/MediaDefs.h>
#include <unistd.h>
#include <fcntl.h>
#include "driver/sound.h"
#include "LegacyAudioDevice.h"
LegacyAudioDevice::LegacyAudioDevice( const char *name, int32 id )
{
size_t buffer_size;
fInitOK = false;
//open the device driver
fd = open( name, O_RDWR );
if ( fd == 0 ) {
goto init_err1;
}
input_flavor.name = const_cast<char *>( name );
input_flavor.info = "legacy audio input";
input_flavor.kinds = B_BUFFER_PRODUCER|B_CONTROLLABLE|B_PHYSICAL_INPUT;
input_flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
input_flavor.internal_id = 2 * id;
input_flavor.possible_count = 1;
input_flavor.in_format_count = 0;
input_flavor.in_format_flags = 0;
input_flavor.in_formats = NULL;
input_flavor.out_format_count = 1;
input_flavor.out_format_flags = 0;
input_flavor.out_formats = &input_format;
//get driver capture buffer size
ioctl( fd, SOUND_GET_CAPTURE_PREFERRED_BUF_SIZE, &buffer_size, 0 );
ioctl( fd, SOUND_SET_CAPTURE_PREFERRED_BUF_SIZE, buffer_size, 0 );
input_format.type = B_MEDIA_RAW_AUDIO;
input_format.u.raw_audio.frame_rate = 44100.0;
input_format.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
input_format.u.raw_audio.channel_count = 2;
input_format.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
input_format.u.raw_audio.buffer_size = buffer_size;
//allocate input completion semaphore
in_sem = create_sem( 0, "legacy audio input completion" );
if ( in_sem < B_OK ) {
goto init_err2;
}
//tell the driver about the capture completion semaphore
ioctl( fd, SOUND_SET_CAPTURE_COMPLETION_SEM, &in_sem, 0 );
output_flavor.name = const_cast<char *>( name );
output_flavor.info = "legacy audio output";
output_flavor.kinds = B_BUFFER_CONSUMER|B_TIME_SOURCE|B_CONTROLLABLE|B_PHYSICAL_OUTPUT;
output_flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
output_flavor.internal_id = 2 * id + 1;
output_flavor.possible_count = 1;
output_flavor.in_format_count = 1;
output_flavor.in_format_flags = 0;
output_flavor.in_formats = &output_format;
output_flavor.out_format_count = 0;
output_flavor.out_format_flags = 0;
output_flavor.out_formats = NULL;
//get driver playback buffer size
ioctl( fd, SOUND_GET_PLAYBACK_PREFERRED_BUF_SIZE, &buffer_size, 0 );
ioctl( fd, SOUND_SET_PLAYBACK_PREFERRED_BUF_SIZE, buffer_size, 0 );
output_format.type = B_MEDIA_RAW_AUDIO;
output_format.u.raw_audio.frame_rate = 44100.0;
output_format.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
output_format.u.raw_audio.channel_count = 2;
output_format.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
output_format.u.raw_audio.buffer_size = buffer_size;
//allocate output completion semaphore
out_sem = create_sem( 0, "legacy audio output completion" );
if ( out_sem < B_OK ) {
goto init_err3;
}
//tell the driver about the playback completion semaphore
ioctl( fd, SOUND_SET_PLAYBACK_COMPLETION_SEM, &out_sem, 0 );
fInitOK = true;
return;
init_err3:
delete_sem( in_sem );
init_err2:
close( fd );
init_err1:
return;
}
LegacyAudioDevice::~LegacyAudioDevice()
{
if ( fInitOK == false ) {
return;
}
//cleaning up...
if ( out_sem > B_OK ) {
delete_sem( out_sem );
}
if ( in_sem > B_OK ) {
delete_sem( in_sem );
}
if ( fd != 0 ) {
close( fd );
}
//...done
}
int32
LegacyAudioDevice::Input_Thread()
{
while ( 1 ) {
/* send IO request */
ioctl( fd, SOUND_UNSAFE_READ, buffer, sizeof( buffer ) );
/* Wait for IO completion:
The only acceptable response is B_OK. Everything else means
the thread should quit. */
_ if ( acquire_sem( in_sem ) != B_OK ) {
break;
}
#if 0
/* Send buffers only if the node is running and the output has been
* enabled */
if ( !fRunning || !fEnabled ) {
continue;
}
BAutolock _(fLock);
/* Fetch a buffer from the buffer group */
BBuffer *buffer = fBufferGroup->RequestBuffer(
4 * fConnectedFormat.display.line_width *
fConnectedFormat.display.line_count, 0LL);
if (!buffer)
continue;
/* Fill out the details about this buffer. */
media_header *h = buffer->Header();
h->type = B_MEDIA_RAW_VIDEO;
h->time_source = TimeSource()->ID();
h->size_used = 4 * fConnectedFormat.display.line_width *
fConnectedFormat.display.line_count;
/* For a buffer originating from a device, you might want to calculate
* this based on the PerformanceTimeFor the time your buffer arrived at
* the hardware (plus any applicable adjustments). */
h->start_time = fPerformanceTimeBase +
(bigtime_t)
((fFrame - fFrameBase) *
(1000000 / fConnectedFormat.field_rate));
h->file_pos = 0;
h->orig_size = 0;
h->data_offset = 0;
h->u.raw_video.field_gamma = 1.0;
h->u.raw_video.field_sequence = fFrame;
h->u.raw_video.field_number = 0;
h->u.raw_video.pulldown_number = 0;
h->u.raw_video.first_active_line = 1;
h->u.raw_video.line_count = fConnectedFormat.display.line_count;
/* Fill in a pattern */
uint32 *p = (uint32 *)buffer->Data();
for (int y=0;y<fConnectedFormat.display.line_count;y++)
for (int x=0;x<fConnectedFormat.display.line_width;x++)
*(p++) = ((((x+y)^0^x)+fFrame) & 0xff) * (0x01010101 & fColor);
/* Send the buffer on down to the consumer */
if (SendBuffer(buffer, fOutput.destination) < B_OK) {
PRINTF(-1, ("FrameGenerator: Error sending buffer\n"));
/* If there is a problem sending the buffer, return it to its
* buffer group. */
buffer->Recycle();
}
#endif
}
return B_OK;
}
int32
LegacyAudioDevice::Output_Thread()
{
while (1) {
}
return B_OK;
}
@@ -0,0 +1,76 @@
/*****************************************************************************/
// LegacyAudioDevice class
//
// [Class Description]
//
//
// Copyright (c) 2002 OpenBeOS Project
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#ifndef _LEGACY_AUDIO_DEVICE_H
#define _LEGACY_AUDIO_DEVICE_H
#include <media/MediaAddOn.h>
#include <media/MediaFormats.h>
class LegacyAudioDevice
{
public:
LegacyAudioDevice( const char *name, int32 id );
~LegacyAudioDevice();
bool CheckInit()
{ return fInitOK; }
flavor_info *GetInputFlavor()
{ return &input_flavor; }
flavor_info *GetOutputFlavor()
{ return &output_flavor; }
media_format *GetInputFormat()
{ return &input_format; }
media_format *GetOutputFormat()
{ return &output_format; }
protected:
int32 Input_Thread();
int32 Output_Thread();
private:
bool fInitOK;
int fd; //file-descriptor of hw device
flavor_info input_flavor;
media_format input_format;
sem_id in_sem; //input completion semaphore
thread_id input_thread; //input thread
flavor_info output_flavor;
media_format output_format;
sem_id out_sem; //output completion semaphore
thread_id output_thread; //output thread
};
#endif
@@ -0,0 +1,26 @@
#include <fcntl.h>
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>
#include <media/Buffer.h>
#include <media/BufferGroup.h>
#include <media/ParameterWeb.h>
#include <media/TimeSource.h>
#include <support/Autolock.h>
#include <support/Debug.h>
#include "driver/sound.h"
//#include "LegacyAudioProducer.h"
#if 0
LegacyAudioProducer::LegacyAudioProducer( BMediaAddOn *addon, const char *name, int32 internal_id )
: BMediaNode( name ), BMediaEventLooper(), BBufferProducer( B_MEDIA_RAW_AUDIO ), BControllable()
{
}
#endif
@@ -0,0 +1,121 @@
#ifndef _LEGACY_AUDIO_PRODUCER_H
#define _LEGACY_AUDIO_PRODUCER_H
#include <kernel/OS.h>
#include <media/BufferProducer.h>
#include <media/Controllable.h>
#include <media/MediaAddOn.h>
#include <media/MediaDefs.h>
#include <media/MediaEventLooper.h>
#include <media/MediaNode.h>
#include <support/Locker.h>
class LegacyAudioProducer : public virtual BMediaEventLooper,
public virtual BBufferProducer,
public virtual BControllable
{
public:
LegacyAudioProducer( BMediaAddOn *addon, const char *name, int32 internal_id );
virtual ~LegacyAudioProducer();
virtual status_t InitCheck() const { return fInitStatus; }
/* BMediaNode */
public:
virtual port_id ControlPort() const;
virtual BMediaAddOn *AddOn( int32 *internal_id ) const;
virtual status_t HandleMessage( int32 message, const void *data, size_t size );
protected:
virtual void Preroll() {}
virtual void SetTimeSource( BTimeSource *time_source );
virtual status_t RequestCompleted( const media_request_info &info );
/* BMediaEventLooper */
protected:
virtual void NodeRegistered();
virtual void Start( bigtime_t performance_time );
virtual void Stop( bigtime_t performance_time, bool immediate );
virtual void Seek( bigtime_t media_time, bigtime_t performance_time );
virtual void TimeWarp( bigtime_t at_real_time, bigtime_t to_performance_time );
virtual status_t AddTimer( bigtime_t at_performance_time, int32 cookie );
virtual void SetRunMode( run_mode mode );
virtual void HandleEvent( const media_timed_event *event, bigtime_t lateness, bool realTimeEvent = false );
virtual void CleanUpEvent( const media_timed_event *event );
virtual bigtime_t OfflineTime();
virtual void ControlLoop();
virtual status_t DeleteHook( BMediaNode *node );
/* BBufferProducer */
protected:
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 VideoClippingChanged( const media_source &for_source, int16 num_shorts, int16 *clip_data,
const media_video_display_info &display, int32 *_deprecated_ )
{ return B_ERROR; }
virtual status_t GetLatency( bigtime_t *out_latency );
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 status_t SetPlayRate( int32 numer,int32 denom );
virtual void AdditionalBufferRequested( const media_source & source, media_buffer_id prev_buffer,
bigtime_t prev_time, const media_seek_tag *prev_tag );
virtual void LatencyChanged( const media_source &source, const media_destination &destination,
bigtime_t new_latency, uint32 flags );
/* BControllable */
protected:
virtual status_t GetParameterValue( int32 id, bigtime_t *last_change, void *value, size_t *size );
virtual void SetParameterValue( int32 id, bigtime_t when, const void *value, size_t size );
virtual status_t StartControlPanel( BMessenger *out_messenger )
{ return B_ERROR; }
/* state */
private:
void HandleStart( bigtime_t performance_time );
void HandleStop();
void HandleTimeWarp( bigtime_t performance_time );
void HandleSeek( bigtime_t performance_time );
status_t fInitStatus;
int32 fInternalID;
BMediaAddOn *fAddOn;
BLocker fLock;
BBufferGroup *fBufferGroup;
thread_id fThread;
sem_id fFrameSync;
static int32 _run_thread_( void *data );
int32 RunThread();
#if 0
/* The remaining variables should be declared volatile, but they
* are not here to improve the legibility of the sample code. */
uint32 fFrame;
uint32 fFrameBase;
bigtime_t fPerformanceTimeBase;
bigtime_t fProcessingLatency;
media_output fOutput;
media_raw_video_format fConnectedFormat;
bool fRunning;
bool fConnected;
bool fEnabled;
enum { P_COLOR };
uint32 fColor;
bigtime_t fLastColorChange;
#endif
};
#endif
@@ -0,0 +1,67 @@
#include <support/Autolock.h>
#include <media/MediaDefs.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <media/MediaAddOn.h>
#include "LegacyMediaAddOn.h"
#include "LegacyAudioConsumer.h"
#include "LegacyAudioProducer.h"
LegacyMediaAddOn::LegacyMediaAddOn( image_id imid )
: BMediaAddOn( imid )
{
fInitStatus = B_NO_INIT;
consumer = new LegacyAudioConsumer( this, "ymf744/1", 0 );
//producer = new LegacyAudioProducer( "maestro2/1" );
fInitStatus = B_OK;
}
LegacyMediaAddOn::~LegacyMediaAddOn()
{
delete consumer;
//delete producer;
}
status_t
LegacyMediaAddOn::InitCheck( const char **out_failure_text )
{
return fInitStatus;
}
int32
LegacyMediaAddOn::CountFlavors()
{
return 0;
}
status_t
LegacyMediaAddOn::GetFlavorAt( int32 n, const flavor_info **out_info )
{
return B_ERROR;
}
BMediaNode *
LegacyMediaAddOn::InstantiateNodeFor( const flavor_info *info, BMessage *config, status_t *out_error )
{
return NULL;
}
BMediaAddOn *
make_media_addon( image_id imid )
{
return new LegacyMediaAddOn( imid );
}
@@ -0,0 +1,47 @@
#ifndef _LEGACY_MEDIA_ADDON_H
#define _LEGACY_MEDIA_ADDON_H
#include <media/MediaAddOn.h>
#include "LegacyAudioConsumer.h"
//#include "LegacyAudioProducer.h"
class LegacyMediaAddOn : public BMediaAddOn
{
public:
LegacyMediaAddOn( image_id imid );
virtual ~LegacyMediaAddOn();
virtual status_t InitCheck( const char **out_failure_text );
virtual int32 CountFlavors();
virtual status_t GetFlavorAt( int32 n, const flavor_info **out_info );
virtual BMediaNode *InstantiateNodeFor( const flavor_info *info, BMessage *config, status_t *out_error );
virtual status_t GetConfigurationFor( BMediaNode *node, BMessage *message )
{ return B_ERROR; }
virtual status_t SaveConfigInfo( BMediaNode *node, BMessage *message )
{ return B_OK; }
virtual bool WantsAutoStart()
{ return false; }
virtual status_t AutoStart( int in_count, BMediaNode **out_node, int32 *out_internal_id, bool *out_has_more )
{ return B_ERROR; }
private:
status_t fInitStatus;
flavor_info fFlavorInfo;
media_format fMediaFormat;
//BList *consumers;
//BList *producers;
LegacyAudioConsumer *consumer;
};
extern "C" _EXPORT BMediaAddOn *make_media_addon( image_id you );
#endif
@@ -0,0 +1,21 @@
#ifndef _DRIVER_IO_H
#define _DRIVER_IO_H
#include <unistd.h>
#include <fcntl.h>
#include "driver/sound.h"
#define DRIVER_GET_PARAMS(x...) ioctl( fd, SOUND_GET_PARAMS, x )
#define DRIVER_SET_PARAMS(x...) ioctl( fd, SOUND_SET_PARAMS, x )
#define DRIVER_SET_PLAYBACK_COMPLETION_SEM(x...) ioctl( fd, SOUND_SET_PLAYBACK_COMPLETION_SEM, x )
#define DRIVER_SET_CAPTURE_COMPLETION_SEM(x...) ioctl( fd, SOUND_SET_CAPTURE_COMPLETION_SEM, x )
#define DRIVER_UNSAFE_WRITE(x...) ioctl( fd, SOUND_UNSAFE_WRITE, x )
#define DRIVER_UNSAFE_READ(x...) ioctl( fd, SOUND_UNSAFE_READ, x )
#define DRIVER_LOCK_FOR_DMA(x...) ioctl( fd, SOUND_LOCK_FOR_DMA, x )
#define DRIVER_SET_CAPTURE_PREFERRED_BUF_SIZE(x...) ioctl( fd, SOUND_SET_CAPTURE_PREFERRED_BUF_SIZE, x )
#define DRIVER_SET_PLAYBACK_PREFERRED_BUF_SIZE(x...) ioctl( fd, SOUND_SET_PLAYBACK_PREFERRED_BUF_SIZE, x )
#define DRIVER_GET_CAPTURE_PREFERRED_BUF_SIZE(x...) ioctl( fd, SOUND_GET_CAPTURE_PREFERRED_BUF_SIZE, x )
#define DRIVER_GET_PLAYBACK_PREFERRED_BUF_SIZE(x...) ioctl( fd, SOUND_GET_PLAYBACK_PREFERRED_BUF_SIZE, x )
#endif