From dc6545d6f24bc72a5fcad792a9cc9ed5455f9678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 6 Feb 2020 11:33:34 +0100 Subject: [PATCH] Add patchset for my portaudio attempt Mostly stubs. --- .../patches/portaudio-19-git.patchset | 907 ++++++++++++++++++ 1 file changed, 907 insertions(+) create mode 100644 media-libs/portaudio/patches/portaudio-19-git.patchset diff --git a/media-libs/portaudio/patches/portaudio-19-git.patchset b/media-libs/portaudio/patches/portaudio-19-git.patchset new file mode 100644 index 000000000..8317ac258 --- /dev/null +++ b/media-libs/portaudio/patches/portaudio-19-git.patchset @@ -0,0 +1,907 @@ +From 8abb8d0de9ab231a4de8bdced0ac70f3008bb2c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= +Date: Thu, 6 Feb 2020 11:29:50 +0100 +Subject: [PATCH] Initial attempt at a Haiku port + +I had this code sitting on my hard disk since 2016. + +Currently the implementation is stubbed out. +--- + Makefile.in | 1 + + configure.in | 16 + + src/hostapi/haiku/pa_haiku.cpp | 820 +++++++++++++++++++++++++++++++++ + src/os/unix/pa_unix_hostapis.c | 5 + + 4 files changed, 842 insertions(+) + create mode 100644 src/hostapi/haiku/pa_haiku.cpp + +diff --git a/Makefile.in b/Makefile.in +index 5e1a764..f9dba02 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -144,6 +144,7 @@ SRC_DIRS = \ + src/hostapi/asio \ + src/hostapi/coreaudio \ + src/hostapi/dsound \ ++ src/hostapi/haiku \ + src/hostapi/jack \ + src/hostapi/oss \ + src/hostapi/wasapi \ +diff --git a/configure.in b/configure.in +index b2129ba..989e939 100644 +--- a/configure.in ++++ b/configure.in +@@ -393,6 +393,22 @@ case "${host_os}" in + SHARED_FLAGS="" + ;; + ++ haiku* ) ++ dnl Haiku configuration ++ ++ AC_DEFINE(PA_USE_HAIKU,1) ++ ++ CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/unix" ++ # -Werror ++ LIBS="-lmedia" ++ ++ SHARED_FLAGS="$LIBS -shared" ++ #CFLAGS="$CFLAGS" ++ CXXFLAGS="$CFLAGS" ++ OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/common/pa_ringbuffer.o src/hostapi/haiku/pa_haiku.o" ++ PADLL="libportaudio.so" ++ ;; ++ + *) + dnl Unix configuration + +diff --git a/src/hostapi/haiku/pa_haiku.cpp b/src/hostapi/haiku/pa_haiku.cpp +new file mode 100644 +index 0000000..0607513 +--- /dev/null ++++ b/src/hostapi/haiku/pa_haiku.cpp +@@ -0,0 +1,820 @@ ++/* ++ * $Id: pa_haiku.cpp 1668 2011-05-02 17:07:11Z rossb $ ++ * Haiku implementation by: ++ * François Revol ++ * ++ * Based on the Open Source API proposed by Ross Bencina ++ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk ++ * ++ * 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. ++ */ ++ ++/* ++ * The text above constitutes the entire PortAudio license; however, ++ * the PortAudio community also makes the following non-binding requests: ++ * ++ * Any person wishing to distribute modifications to the Software is ++ * requested to send the modifications to the original developer so that ++ * they can be incorporated into the canonical version. It is also ++ * requested that these non-binding requests be included along with the ++ * license above. ++ */ ++ ++/** @file ++ @ingroup common_src ++ ++ @brief Haiku implementation of support for a host API. ++ ++ This file is provided as a starting point for implementing support for ++ a new host API. It provides examples of how the common code can be used. ++ ++ @note IMPLEMENT ME comments are used to indicate functionality ++ which much be customised for each implementation. ++*/ ++ ++ ++#include /* strlen() */ ++ ++#include "pa_util.h" ++#include "pa_allocation.h" ++#include "pa_hostapi.h" ++#include "pa_stream.h" ++#include "pa_cpuload.h" ++#include "pa_process.h" ++#include "pa_debugprint.h" ++ ++ ++/* prototypes for functions declared in this file */ ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif /* __cplusplus */ ++ ++PaError PaHaiku_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ ++ ++static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); ++static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, ++ const PaStreamParameters *inputParameters, ++ const PaStreamParameters *outputParameters, ++ double sampleRate ); ++static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, ++ PaStream** s, ++ const PaStreamParameters *inputParameters, ++ const PaStreamParameters *outputParameters, ++ double sampleRate, ++ unsigned long framesPerBuffer, ++ PaStreamFlags streamFlags, ++ PaStreamCallback *streamCallback, ++ void *userData ); ++static PaError CloseStream( PaStream* stream ); ++static PaError StartStream( PaStream *stream ); ++static PaError StopStream( PaStream *stream ); ++static PaError AbortStream( PaStream *stream ); ++static PaError IsStreamStopped( PaStream *s ); ++static PaError IsStreamActive( PaStream *stream ); ++static PaTime GetStreamTime( PaStream *stream ); ++static double GetStreamCpuLoad( PaStream* stream ); ++static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); ++static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); ++static signed long GetStreamReadAvailable( PaStream* stream ); ++static signed long GetStreamWriteAvailable( PaStream* stream ); ++ ++ ++/* IMPLEMENT ME: a macro like the following one should be used for reporting ++ host errors */ ++#define PA_HAIKU_SET_LAST_HOST_ERROR( errorCode, errorText ) \ ++ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) ++ ++/* PaHaikuHostApiRepresentation - host api datastructure specific to this implementation */ ++ ++typedef struct ++{ ++ PaUtilHostApiRepresentation inheritedHostApiRep; ++ PaUtilStreamInterface callbackStreamInterface; ++ PaUtilStreamInterface blockingStreamInterface; ++ ++ PaUtilAllocationGroup *allocations; ++ ++ /* implementation specific data goes here */ ++} ++PaHaikuHostApiRepresentation; /* IMPLEMENT ME: rename this */ ++ ++ ++PaError PaHaiku_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) ++{ ++ PaError result = paNoError; ++ int i, deviceCount; ++ PaHaikuHostApiRepresentation *haikuHostApi; ++ PaDeviceInfo *deviceInfoArray; ++ ++ PA_DEBUG(("PaHaiku_Initialize in \n")); ++ haikuHostApi = (PaHaikuHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaHaikuHostApiRepresentation) ); ++ if( !haikuHostApi ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ ++ haikuHostApi->allocations = PaUtil_CreateAllocationGroup(); ++ if( !haikuHostApi->allocations ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ ++ *hostApi = &haikuHostApi->inheritedHostApiRep; ++ (*hostApi)->info.structVersion = 1; ++ (*hostApi)->info.type = paInDevelopment; /* IMPLEMENT ME: change to correct type id */ ++ (*hostApi)->info.name = "Haiku implementation"; /* IMPLEMENT ME: change to correct name */ ++ ++ (*hostApi)->info.defaultInputDevice = paNoDevice; /* IMPLEMENT ME */ ++ (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */ ++ ++ (*hostApi)->info.deviceCount = 0; ++ ++ deviceCount = 0; /* IMPLEMENT ME */ ++ ++ if( deviceCount > 0 ) ++ { ++ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( ++ haikuHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount ); ++ if( !(*hostApi)->deviceInfos ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ ++ /* allocate all device info structs in a contiguous block */ ++ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( ++ haikuHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount ); ++ if( !deviceInfoArray ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ ++ for( i=0; i < deviceCount; ++i ) ++ { ++ PaDeviceInfo *deviceInfo = &deviceInfoArray[i]; ++ deviceInfo->structVersion = 2; ++ deviceInfo->hostApi = hostApiIndex; ++ deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg: ++ deviceName = (char*)PaUtil_GroupAllocateMemory( haikuHostApi->allocations, strlen(srcName) + 1 ); ++ if( !deviceName ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ strcpy( deviceName, srcName ); ++ deviceInfo->name = deviceName; ++ */ ++ ++ deviceInfo->maxInputChannels = 0; /* IMPLEMENT ME */ ++ deviceInfo->maxOutputChannels = 0; /* IMPLEMENT ME */ ++ ++ deviceInfo->defaultLowInputLatency = 0.; /* IMPLEMENT ME */ ++ deviceInfo->defaultLowOutputLatency = 0.; /* IMPLEMENT ME */ ++ deviceInfo->defaultHighInputLatency = 0.; /* IMPLEMENT ME */ ++ deviceInfo->defaultHighOutputLatency = 0.; /* IMPLEMENT ME */ ++ ++ deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */ ++ ++ (*hostApi)->deviceInfos[i] = deviceInfo; ++ ++(*hostApi)->info.deviceCount; ++ } ++ } ++ ++ (*hostApi)->Terminate = Terminate; ++ (*hostApi)->OpenStream = OpenStream; ++ (*hostApi)->IsFormatSupported = IsFormatSupported; ++ ++ PaUtil_InitializeStreamInterface( &haikuHostApi->callbackStreamInterface, CloseStream, StartStream, ++ StopStream, AbortStream, IsStreamStopped, IsStreamActive, ++ GetStreamTime, GetStreamCpuLoad, ++ PaUtil_DummyRead, PaUtil_DummyWrite, ++ PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); ++ ++ PaUtil_InitializeStreamInterface( &haikuHostApi->blockingStreamInterface, CloseStream, StartStream, ++ StopStream, AbortStream, IsStreamStopped, IsStreamActive, ++ GetStreamTime, PaUtil_DummyGetCpuLoad, ++ ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); ++ ++ return result; ++ ++error: ++ if( haikuHostApi ) ++ { ++ if( haikuHostApi->allocations ) ++ { ++ PaUtil_FreeAllAllocations( haikuHostApi->allocations ); ++ PaUtil_DestroyAllocationGroup( haikuHostApi->allocations ); ++ } ++ ++ PaUtil_FreeMemory( haikuHostApi ); ++ } ++ return result; ++} ++ ++ ++static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) ++{ ++ PaHaikuHostApiRepresentation *haikuHostApi = (PaHaikuHostApiRepresentation*)hostApi; ++ ++ /* ++ IMPLEMENT ME: ++ - clean up any resources not handled by the allocation group ++ */ ++ ++ if( haikuHostApi->allocations ) ++ { ++ PaUtil_FreeAllAllocations( haikuHostApi->allocations ); ++ PaUtil_DestroyAllocationGroup( haikuHostApi->allocations ); ++ } ++ ++ PaUtil_FreeMemory( haikuHostApi ); ++} ++ ++ ++static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, ++ const PaStreamParameters *inputParameters, ++ const PaStreamParameters *outputParameters, ++ double sampleRate ) ++{ ++ int inputChannelCount, outputChannelCount; ++ PaSampleFormat inputSampleFormat, outputSampleFormat; ++ ++ PA_DEBUG(("IsFormatSupported in \n")); ++ if( inputParameters ) ++ { ++ inputChannelCount = inputParameters->channelCount; ++ inputSampleFormat = inputParameters->sampleFormat; ++ ++ /* all standard sample formats are supported by the buffer adapter, ++ this implementation doesn't support any custom sample formats */ ++ if( inputSampleFormat & paCustomFormat ) ++ return paSampleFormatNotSupported; ++ ++ /* unless alternate device specification is supported, reject the use of ++ paUseHostApiSpecificDeviceSpecification */ ++ ++ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) ++ return paInvalidDevice; ++ ++ /* check that input device can support inputChannelCount */ ++ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) ++ return paInvalidChannelCount; ++ ++ /* validate inputStreamInfo */ ++ if( inputParameters->hostApiSpecificStreamInfo ) ++ return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ ++ } ++ else ++ { ++ inputChannelCount = 0; ++ } ++ ++ if( outputParameters ) ++ { ++ outputChannelCount = outputParameters->channelCount; ++ outputSampleFormat = outputParameters->sampleFormat; ++ ++ /* all standard sample formats are supported by the buffer adapter, ++ this implementation doesn't support any custom sample formats */ ++ if( outputSampleFormat & paCustomFormat ) ++ return paSampleFormatNotSupported; ++ ++ /* unless alternate device specification is supported, reject the use of ++ paUseHostApiSpecificDeviceSpecification */ ++ ++ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) ++ return paInvalidDevice; ++ ++ /* check that output device can support outputChannelCount */ ++ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) ++ return paInvalidChannelCount; ++ ++ /* validate outputStreamInfo */ ++ if( outputParameters->hostApiSpecificStreamInfo ) ++ return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ ++ } ++ else ++ { ++ outputChannelCount = 0; ++ } ++ ++ /* ++ IMPLEMENT ME: ++ ++ - if a full duplex stream is requested, check that the combination ++ of input and output parameters is supported if necessary ++ ++ - check that the device supports sampleRate ++ ++ Because the buffer adapter handles conversion between all standard ++ sample formats, the following checks are only required if paCustomFormat ++ is implemented, or under some other unusual conditions. ++ ++ - check that input device can support inputSampleFormat, or that ++ we have the capability to convert from inputSampleFormat to ++ a native format ++ ++ - check that output device can support outputSampleFormat, or that ++ we have the capability to convert from outputSampleFormat to ++ a native format ++ */ ++ ++ ++ /* suppress unused variable warnings */ ++ (void) sampleRate; ++ ++ return paFormatIsSupported; ++} ++ ++/* PaHaikuStream - a stream data structure specifically for this implementation */ ++ ++typedef struct PaHaikuStream ++{ ++ PaUtilStreamRepresentation streamRepresentation; ++ PaUtilCpuLoadMeasurer cpuLoadMeasurer; ++ PaUtilBufferProcessor bufferProcessor; ++ ++ /* IMPLEMENT ME: ++ - implementation specific data goes here ++ */ ++ unsigned long framesPerHostCallback; /* just an example */ ++} ++PaHaikuStream; ++ ++/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ ++ ++static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, ++ PaStream** s, ++ const PaStreamParameters *inputParameters, ++ const PaStreamParameters *outputParameters, ++ double sampleRate, ++ unsigned long framesPerBuffer, ++ PaStreamFlags streamFlags, ++ PaStreamCallback *streamCallback, ++ void *userData ) ++{ ++ PaError result = paNoError; ++ PaHaikuHostApiRepresentation *haikuHostApi = (PaHaikuHostApiRepresentation*)hostApi; ++ PaHaikuStream *stream = 0; ++ unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */ ++ int inputChannelCount, outputChannelCount; ++ PaSampleFormat inputSampleFormat, outputSampleFormat; ++ PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; ++ ++ ++ if( inputParameters ) ++ { ++ inputChannelCount = inputParameters->channelCount; ++ inputSampleFormat = inputParameters->sampleFormat; ++ ++ /* unless alternate device specification is supported, reject the use of ++ paUseHostApiSpecificDeviceSpecification */ ++ ++ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) ++ return paInvalidDevice; ++ ++ /* check that input device can support inputChannelCount */ ++ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) ++ return paInvalidChannelCount; ++ ++ /* validate inputStreamInfo */ ++ if( inputParameters->hostApiSpecificStreamInfo ) ++ return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ ++ ++ /* IMPLEMENT ME - establish which host formats are available */ ++ hostInputSampleFormat = ++ PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); ++ } ++ else ++ { ++ inputChannelCount = 0; ++ inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */ ++ } ++ ++ if( outputParameters ) ++ { ++ outputChannelCount = outputParameters->channelCount; ++ outputSampleFormat = outputParameters->sampleFormat; ++ ++ /* unless alternate device specification is supported, reject the use of ++ paUseHostApiSpecificDeviceSpecification */ ++ ++ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) ++ return paInvalidDevice; ++ ++ /* check that output device can support inputChannelCount */ ++ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) ++ return paInvalidChannelCount; ++ ++ /* validate outputStreamInfo */ ++ if( outputParameters->hostApiSpecificStreamInfo ) ++ return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ ++ ++ /* IMPLEMENT ME - establish which host formats are available */ ++ hostOutputSampleFormat = ++ PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); ++ } ++ else ++ { ++ outputChannelCount = 0; ++ outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */ ++ } ++ ++ /* ++ IMPLEMENT ME: ++ ++ ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? ) ++ ++ - check that input device can support inputSampleFormat, or that ++ we have the capability to convert from outputSampleFormat to ++ a native format ++ ++ - check that output device can support outputSampleFormat, or that ++ we have the capability to convert from outputSampleFormat to ++ a native format ++ ++ - if a full duplex stream is requested, check that the combination ++ of input and output parameters is supported ++ ++ - check that the device supports sampleRate ++ ++ - alter sampleRate to a close allowable rate if possible / necessary ++ ++ - validate suggestedInputLatency and suggestedOutputLatency parameters, ++ use default values where necessary ++ */ ++ ++ ++ ++ ++ /* validate platform specific flags */ ++ if( (streamFlags & paPlatformSpecificFlags) != 0 ) ++ return paInvalidFlag; /* unexpected platform specific flag */ ++ ++ ++ stream = (PaHaikuStream*)PaUtil_AllocateMemory( sizeof(PaHaikuStream) ); ++ if( !stream ) ++ { ++ result = paInsufficientMemory; ++ goto error; ++ } ++ ++ if( streamCallback ) ++ { ++ PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ++ &haikuHostApi->callbackStreamInterface, streamCallback, userData ); ++ } ++ else ++ { ++ PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ++ &haikuHostApi->blockingStreamInterface, streamCallback, userData ); ++ } ++ ++ PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); ++ ++ ++ /* we assume a fixed host buffer size in this example, but the buffer processor ++ can also support bounded and unknown host buffer sizes by passing ++ paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of ++ paUtilFixedHostBufferSize below. */ ++ ++ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, ++ inputChannelCount, inputSampleFormat, hostInputSampleFormat, ++ outputChannelCount, outputSampleFormat, hostOutputSampleFormat, ++ sampleRate, streamFlags, framesPerBuffer, ++ framesPerHostBuffer, paUtilFixedHostBufferSize, ++ streamCallback, userData ); ++ if( result != paNoError ) ++ goto error; ++ ++ ++ /* ++ IMPLEMENT ME: initialise the following fields with estimated or actual ++ values. ++ */ ++ stream->streamRepresentation.streamInfo.inputLatency = ++ (PaTime)PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) / sampleRate; /* inputLatency is specified in _seconds_ */ ++ stream->streamRepresentation.streamInfo.outputLatency = ++ (PaTime)PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) / sampleRate; /* outputLatency is specified in _seconds_ */ ++ stream->streamRepresentation.streamInfo.sampleRate = sampleRate; ++ ++ ++ /* ++ IMPLEMENT ME: ++ - additional stream setup + opening ++ */ ++ ++ stream->framesPerHostCallback = framesPerHostBuffer; ++ ++ *s = (PaStream*)stream; ++ ++ return result; ++ ++error: ++ if( stream ) ++ PaUtil_FreeMemory( stream ); ++ ++ return result; ++} ++ ++/* ++ ExampleHostProcessingLoop() illustrates the kind of processing which may ++ occur in a host implementation. ++ ++*/ ++static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)userData; ++ PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */ ++ int callbackResult; ++ unsigned long framesProcessed; ++ ++ PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); ++ ++ /* ++ IMPLEMENT ME: ++ - generate timing information ++ - handle buffer slips ++ */ ++ ++ /* ++ If you need to byte swap or shift inputBuffer to convert it into a ++ portaudio format, do it here. ++ */ ++ ++ ++ ++ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ ); ++ ++ /* ++ depending on whether the host buffers are interleaved, non-interleaved ++ or a mixture, you will want to call PaUtil_SetInterleaved*Channels(), ++ PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here. ++ */ ++ ++ PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); ++ PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, ++ 0, /* first channel of inputBuffer is channel 0 */ ++ inputBuffer, ++ 0 ); /* 0 - use inputChannelCount passed to init buffer processor */ ++ ++ PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); ++ PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, ++ 0, /* first channel of outputBuffer is channel 0 */ ++ outputBuffer, ++ 0 ); /* 0 - use outputChannelCount passed to init buffer processor */ ++ ++ /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing() ++ in general you would pass paContinue for normal operation, and ++ paComplete to drain the buffer processor's internal output buffer. ++ You can check whether the buffer processor's output buffer is empty ++ using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor ) ++ */ ++ callbackResult = paContinue; ++ framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); ++ ++ ++ /* ++ If you need to byte swap or shift outputBuffer to convert it to ++ host format, do it here. ++ */ ++ ++ PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); ++ ++ ++ if( callbackResult == paContinue ) ++ { ++ /* nothing special to do */ ++ } ++ else if( callbackResult == paAbort ) ++ { ++ /* IMPLEMENT ME - finish playback immediately */ ++ ++ /* once finished, call the finished callback */ ++ if( stream->streamRepresentation.streamFinishedCallback != 0 ) ++ stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); ++ } ++ else ++ { ++ /* User callback has asked us to stop with paComplete or other non-zero value */ ++ ++ /* IMPLEMENT ME - finish playback once currently queued audio has completed */ ++ ++ /* once finished, call the finished callback */ ++ if( stream->streamRepresentation.streamFinishedCallback != 0 ) ++ stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); ++ } ++} ++ ++ ++/* ++ When CloseStream() is called, the multi-api layer ensures that ++ the stream has already been stopped or aborted. ++*/ ++static PaError CloseStream( PaStream* s ) ++{ ++ PaError result = paNoError; ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* ++ IMPLEMENT ME: ++ - additional stream closing + cleanup ++ */ ++ ++ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); ++ PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); ++ PaUtil_FreeMemory( stream ); ++ ++ return result; ++} ++ ++ ++static PaError StartStream( PaStream *s ) ++{ ++ PaError result = paNoError; ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior */ ++ ++ /* suppress unused function warning. the code in ExampleHostProcessingLoop or ++ something similar should be implemented to feed samples to and from the ++ host after StartStream() is called. ++ */ ++ (void) ExampleHostProcessingLoop; ++ ++ return result; ++} ++ ++ ++static PaError StopStream( PaStream *s ) ++{ ++ PaError result = paNoError; ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior */ ++ ++ return result; ++} ++ ++ ++static PaError AbortStream( PaStream *s ) ++{ ++ PaError result = paNoError; ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior */ ++ ++ return result; ++} ++ ++ ++static PaError IsStreamStopped( PaStream *s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior */ ++ ++ return 0; ++} ++ ++ ++static PaError IsStreamActive( PaStream *s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior */ ++ ++ return 0; ++} ++ ++ ++static PaTime GetStreamTime( PaStream *s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior*/ ++ ++ return 0; ++} ++ ++ ++static double GetStreamCpuLoad( PaStream* s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); ++} ++ ++ ++/* ++ As separate stream interfaces are used for blocking and callback ++ streams, the following functions can be guaranteed to only be called ++ for blocking streams. ++*/ ++ ++static PaError ReadStream( PaStream* s, ++ void *buffer, ++ unsigned long frames ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) buffer; ++ (void) frames; ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior*/ ++ ++ return paNoError; ++} ++ ++ ++static PaError WriteStream( PaStream* s, ++ const void *buffer, ++ unsigned long frames ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) buffer; ++ (void) frames; ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior*/ ++ ++ return paNoError; ++} ++ ++ ++static signed long GetStreamReadAvailable( PaStream* s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior*/ ++ ++ return 0; ++} ++ ++ ++static signed long GetStreamWriteAvailable( PaStream* s ) ++{ ++ PaHaikuStream *stream = (PaHaikuStream*)s; ++ ++ /* suppress unused variable warnings */ ++ (void) stream; ++ ++ /* IMPLEMENT ME, see portaudio.h for required behavior*/ ++ ++ return 0; ++} ++ ++ ++ ++ +diff --git a/src/os/unix/pa_unix_hostapis.c b/src/os/unix/pa_unix_hostapis.c +index a9b4a05..fb9f9b2 100644 +--- a/src/os/unix/pa_unix_hostapis.c ++++ b/src/os/unix/pa_unix_hostapis.c +@@ -50,6 +50,7 @@ PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex + /* Linux AudioScience HPI */ + PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); + PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); ++PaError PaHaiku_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); + PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); + + /** Note that on Linux, ALSA is placed before OSS so that the former is preferred over the latter. +@@ -95,6 +96,10 @@ PaUtilHostApiInitializer *paHostApiInitializers[] = + PaMacCore_Initialize, + #endif + ++#if PA_USE_HAIKU ++ PaHaiku_Initialize, ++#endif ++ + #if PA_USE_SKELETON + PaSkeleton_Initialize, + #endif +-- +2.24.1 +