diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.cpp b/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.cpp new file mode 100644 index 0000000000..dc4c700020 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.cpp @@ -0,0 +1,430 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#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( io_buf1 ) + sizeof( audio_buffer_header ) + mBuffer_size; + + static_cast( io_buf1 )->reserved_1 = sizeof( audio_buffer_header ) + mBuffer_size; + static_cast( 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( 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( &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( 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( ( io_buf == io_buf2 ) ? io_buf1 : io_buf2 ); + + //prepare buffer + memcpy( static_cast( 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( 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; +} diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.h b/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.h new file mode 100644 index 0000000000..50093b7bc5 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioConsumer.h @@ -0,0 +1,121 @@ +#ifndef _LEGACY_AUDIO_CONSUMER_H +#define _LEGACY_AUDIO_CONSUMER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.cpp b/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.cpp new file mode 100644 index 0000000000..c4029e4bc8 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.cpp @@ -0,0 +1,209 @@ +#include +#include +#include + +#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( 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( 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;yRecycle(); + } +#endif + } + + return B_OK; +} + + +int32 +LegacyAudioDevice::Output_Thread() +{ + while (1) { + } + + return B_OK; +} diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.h b/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.h new file mode 100644 index 0000000000..a4f1bf1cc0 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioDevice.h @@ -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 +#include + +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 diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.cpp b/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.cpp new file mode 100644 index 0000000000..1fe67ede3e --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#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 \ No newline at end of file diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.h b/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.h new file mode 100644 index 0000000000..174812c84f --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyAudioProducer.h @@ -0,0 +1,121 @@ +#ifndef _LEGACY_AUDIO_PRODUCER_H +#define _LEGACY_AUDIO_PRODUCER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.cpp b/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.cpp new file mode 100644 index 0000000000..5a25573fd7 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.cpp @@ -0,0 +1,67 @@ +#include +#include + +#include +#include +#include + +#include + +#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 ); +} diff --git a/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.h b/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.h new file mode 100644 index 0000000000..b63787cb56 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/LegacyMediaAddOn.h @@ -0,0 +1,47 @@ +#ifndef _LEGACY_MEDIA_ADDON_H +#define _LEGACY_MEDIA_ADDON_H + +#include + +#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 diff --git a/src/add-ons/media/media-add-ons/legacy/driver_io.h b/src/add-ons/media/media-add-ons/legacy/driver_io.h new file mode 100644 index 0000000000..5f44ae7b73 --- /dev/null +++ b/src/add-ons/media/media-add-ons/legacy/driver_io.h @@ -0,0 +1,21 @@ +#ifndef _DRIVER_IO_H +#define _DRIVER_IO_H + +#include +#include + +#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