diff --git a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp index 6826c867e8..7d1f1d9175 100644 --- a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp +++ b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp @@ -2,28 +2,7 @@ * multiaudio replacement media addon for BeOS * * 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. */ #include #include @@ -1621,7 +1600,21 @@ MultiAudioNode::FillNextBuffer(node_input &input, BBuffer* buffer) case media_raw_audio_format::B_AUDIO_FLOAT: switch(input.fFormat.u.raw_audio.format) { - case media_raw_audio_format::B_AUDIO_FLOAT: + case media_raw_audio_format::B_AUDIO_FLOAT: { + size_t frame_size = input.fInput.format.u.raw_audio.channel_count * sizeof(float); + size_t stride = fDevice->MBL.playback_buffers[input.fBufferCycle][input.fChannelId].stride; + //PRINT(("stride : %i, frame_size : %i, return_playback_buffer_size : %i\n", stride, frame_size, fDevice->MBL.return_playback_buffer_size)); + for(uint32 channel = 0; channel < input.fInput.format.u.raw_audio.channel_count; channel++) { + char *sample_dest = fDevice->MBL.playback_buffers[input.fBufferCycle][input.fChannelId + channel].base; + //char *sample_src = (char*)buffer->Data() + (input.fInput.format.u.raw_audio.channel_count - 1 - channel) * sizeof(int16); + char *sample_src = (char*)buffer->Data() + channel * sizeof(float); + for(uint32 i=fDevice->MBL.return_playback_buffer_size; i>0; i--) { + *(float *)sample_dest = *(float *)sample_src; + sample_dest += stride; + sample_src += frame_size; + } + } + } break; case media_raw_audio_format::B_AUDIO_INT: break; @@ -1688,7 +1681,7 @@ MultiAudioNode::FillNextBuffer(node_input &input, BBuffer* buffer) //char *sample_src = (char*)buffer->Data() + (input.fInput.format.u.raw_audio.channel_count - 1 - channel) * sizeof(int16); char *sample_src = (char*)buffer->Data() + channel * sizeof(int32); for(uint32 i=fDevice->MBL.return_playback_buffer_size; i>0; i--) { - *(int32*)sample_dest = *(int32*)sample_src; + *(int32 *)sample_dest = *(int32 *)sample_src; sample_dest += stride; sample_src += frame_size; } @@ -1745,7 +1738,7 @@ MultiAudioNode::FillNextBuffer(node_input &input, BBuffer* buffer) //char *sample_src = (char*)buffer->Data() + (input.fInput.format.u.raw_audio.channel_count - 1 - channel) * sizeof(int16); char *sample_src = (char*)buffer->Data() + channel * sizeof(int16); for(uint32 i=fDevice->MBL.return_playback_buffer_size; i>0; i--) { - *(int16*)sample_dest = *(int16*)sample_src; + *(int16 *)sample_dest = *(int16 *)sample_src; sample_dest += stride; sample_src += frame_size; } @@ -1819,10 +1812,10 @@ MultiAudioNode::UpdateTimeSource(multi_buffer_info &MBI, multi_buffer_info &oldM //CALLED(); if(fTimeSourceStarted) { bigtime_t perf_time = (bigtime_t)(MBI.played_frames_count / - input.fInput.format.u.raw_audio.frame_rate * 1000000); + input.fInput.format.u.raw_audio.frame_rate * 1000000LL); bigtime_t real_time = MBI.played_real_time; float drift = ((MBI.played_frames_count - oldMBI.played_frames_count) - / input.fInput.format.u.raw_audio.frame_rate * 1000000) + / input.fInput.format.u.raw_audio.frame_rate * 1000000LL) / (MBI.played_real_time - oldMBI.played_real_time); PublishTime(perf_time, real_time, drift); diff --git a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h index 6d7e88edaa..42c54b62b4 100644 --- a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h +++ b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h @@ -2,28 +2,7 @@ * multiaudio replacement media addon for BeOS * * Copyright (c) 2002, 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 _MULTIAUDIONODE_H #define _MULTIAUDIONODE_H @@ -46,88 +25,88 @@ /*bool format_is_acceptible( const media_format & producer_format, const media_format & consumer_format);*/ - - + + class node_input { public: - node_input(media_input &input, media_format format); - ~node_input(); + node_input(media_input &input, media_format format); + ~node_input(); - int32 fChannelId; - media_input fInput; - media_format fPreferredFormat; - media_format fFormat; - uint32 fBufferCycle; - multi_buffer_info fOldMBI; - BBuffer *fBuffer; + int32 fChannelId; + media_input fInput; + media_format fPreferredFormat; + media_format fFormat; + uint32 fBufferCycle; + multi_buffer_info fOldMBI; + BBuffer *fBuffer; }; class node_output { public: - node_output(media_output &output, media_format format); - ~node_output(); + node_output(media_output &output, media_format format); + ~node_output(); - int32 fChannelId; - media_output fOutput; - media_format fPreferredFormat; - media_format fFormat; - - BBufferGroup *fBufferGroup; - bool fOutputEnabled; - uint64 fSamplesSent; - volatile uint32 fBufferCycle; - multi_buffer_info fOldMBI; + int32 fChannelId; + media_output fOutput; + media_format fPreferredFormat; + media_format fFormat; + + BBufferGroup *fBufferGroup; + bool fOutputEnabled; + uint64 fSamplesSent; + volatile uint32 fBufferCycle; + multi_buffer_info fOldMBI; }; class MultiAudioNode : - public BBufferConsumer, - public BBufferProducer, - public BTimeSource, - public BMediaEventLooper, - public BControllable + public BBufferConsumer, + public BBufferProducer, + public BTimeSource, + public BMediaEventLooper, + public BControllable { -protected: -virtual ~MultiAudioNode(void); + protected: + virtual ~MultiAudioNode(void); -public: + public: -explicit MultiAudioNode(BMediaAddOn *addon, char* name, MultiAudioDevice *device, - int32 internal_id, BMessage * config); + explicit MultiAudioNode(BMediaAddOn *addon, char* name, MultiAudioDevice *device, + int32 internal_id, BMessage * config); -virtual status_t InitCheck(void) const; + 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 */ + /*************************/ + /* begin from BMediaNode */ + public: + virtual BMediaAddOn* AddOn( + int32 * internal_id) const; /* Who instantiated you -- or NULL for app class */ -protected: + 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); + 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); + public: + virtual status_t HandleMessage( + int32 message, + const void * data, + size_t size); -/* end from BMediaNode */ -/***********************/ + protected: + virtual void NodeRegistered(void); /* reserved 2 */ + virtual status_t RequestCompleted(const media_request_info &info); + virtual void SetTimeSource(BTimeSource *timeSource); -/******************************/ -/* begin from BBufferConsumer */ + /* end from BMediaNode */ + /***********************/ + + /******************************/ + /* begin from BBufferConsumer */ //included from BMediaAddOn //virtual status_t HandleMessage( @@ -135,260 +114,245 @@ virtual void SetTimeSource(BTimeSource *timeSource); // 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); + /* 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); + /* 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 */ -/****************************/ + /* end from BBufferConsumer */ + /****************************/ -/******************************/ -/* begin from BBufferProducer */ + /******************************/ + /* 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); + virtual status_t FormatSuggestionRequested(media_type type, + int32 quality, + media_format* format); -/* end from BBufferProducer */ -/****************************/ + virtual status_t FormatProposal(const media_source& output, + media_format* format); -/*****************/ -/* BControllable */ -/*****************/ + 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); -/********************************/ -/* start from BMediaEventLooper */ + 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); + virtual void HandleEvent(const media_timed_event *event, + bigtime_t lateness, + bool realTimeEvent = false); -/* end from BMediaEventLooper */ -/******************************/ + /* end from BMediaEventLooper */ + /******************************/ -/********************************/ -/* start from BTimeSource */ + /********************************/ + /* start from BTimeSource */ protected: - virtual void SetRunMode( run_mode mode); - virtual status_t TimeSourceOp( const time_source_op_info &op, - void *_reserved); + virtual void SetRunMode(run_mode mode); + virtual status_t TimeSourceOp(const time_source_op_info &op, + void *_reserved); -/* end from BTimeSource */ -/******************************/ + /* end from BTimeSource */ + /******************************/ -/********************************/ -/* start from BControllable */ + /********************************/ + /* 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 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(); - -/* end from BControllable */ -/******************************/ -protected: + /* end from BControllable */ + /******************************/ -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); + protected: -public: + 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); -static void GetFlavor(flavor_info * outInfo, int32 id); -static void GetFormat(media_format * outFormat); + public: -status_t GetConfigurationFor(BMessage * into_message); + static void GetFlavor(flavor_info * outInfo, int32 id); + static void GetFormat(media_format * outFormat); + + status_t GetConfigurationFor(BMessage * into_message); -private: + private: - MultiAudioNode( /* private unimplemented */ - const MultiAudioNode & clone); + MultiAudioNode(/* private unimplemented */ + const MultiAudioNode & clone); MultiAudioNode & operator=( - const MultiAudioNode & clone); - + const MultiAudioNode & clone); + //void WriteBuffer( BBuffer *buffer, node_input &input ); void WriteZeros(node_input &input, uint32 bufferCycle); void FillWithZeros(node_input &input); void FillNextBuffer(node_input &channel, BBuffer* buffer); - static int32 _run_thread_( void *data ); + static int32 _run_thread_(void *data); int32 RunThread(); status_t StartThread(); status_t StopThread(); - - + + void AllocateBuffers(node_output &channel); - BBuffer* FillNextBuffer( multi_buffer_info &MBI, - 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); - + multi_buffer_info &oldMBI, + node_input &input); + node_output* FindOutput(media_source source); node_input* FindInput(media_destination dest); node_input* FindInput(int32 destinationId); - + void ProcessGroup(BParameterGroup *group, int32 index, int32 &nbParameters); void ProcessMux(BDiscreteParameter *parameter, int32 index); - + status_t fInitCheckStatus; BMediaAddOn *fAddOn; int32 fId; BList fInputs; - + bigtime_t fLatency; BList fOutputs; media_format fPreferredFormat; - + 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 fBuffer_free; - - thread_id fThread; - MultiAudioDevice *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; - BParameterWeb *fWeb; - BMessage fConfig; }; diff --git a/src/add-ons/media/media-add-ons/multi_audio/driver_io.h b/src/add-ons/media/media-add-ons/multi_audio/driver_io.h index 695d3ed859..b030aa58b5 100644 --- a/src/add-ons/media/media-add-ons/multi_audio/driver_io.h +++ b/src/add-ons/media/media-add-ons/multi_audio/driver_io.h @@ -2,28 +2,7 @@ * multiaudio replacement media addon for BeOS * * Copyright (c) 2002, 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 _DRIVER_IO_H #define _DRIVER_IO_H