/[pcsx2_0.9.7]/trunk/3rdparty/portaudio/src/common/pa_front.c
ViewVC logotype

Annotation of /trunk/3rdparty/portaudio/src/common/pa_front.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 1 month ago) by william
File MIME type: text/plain
File size: 54545 byte(s)
committing r3113 initial commit again...
1 william 31 /*
2     * $Id: pa_front.c 1396 2008-11-03 19:31:30Z philburk $
3     * Portable Audio I/O Library Multi-Host API front end
4     * Validate function parameters and manage multiple host APIs.
5     *
6     * Based on the Open Source API proposed by Ross Bencina
7     * Copyright (c) 1999-2008 Ross Bencina, Phil Burk
8     *
9     * Permission is hereby granted, free of charge, to any person obtaining
10     * a copy of this software and associated documentation files
11     * (the "Software"), to deal in the Software without restriction,
12     * including without limitation the rights to use, copy, modify, merge,
13     * publish, distribute, sublicense, and/or sell copies of the Software,
14     * and to permit persons to whom the Software is furnished to do so,
15     * subject to the following conditions:
16     *
17     * The above copyright notice and this permission notice shall be
18     * included in all copies or substantial portions of the Software.
19     *
20     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
24     * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26     * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27     */
28    
29     /*
30     * The text above constitutes the entire PortAudio license; however,
31     * the PortAudio community also makes the following non-binding requests:
32     *
33     * Any person wishing to distribute modifications to the Software is
34     * requested to send the modifications to the original developer so that
35     * they can be incorporated into the canonical version. It is also
36     * requested that these non-binding requests be included along with the
37     * license above.
38     */
39    
40     /** @file
41     @ingroup common_src
42    
43     @brief Implements PortAudio API functions defined in portaudio.h, checks
44     some errors, delegates platform-specific behavior to host API implementations.
45    
46     Implements the functions defined in the PortAudio API (portaudio.h),
47     validates some parameters and checks for state inconsistencies before
48     forwarding API requests to specific Host API implementations (via the
49     interface declared in pa_hostapi.h), and Streams (via the interface
50     declared in pa_stream.h).
51    
52     This file manages initialization and termination of Host API
53     implementations via initializer functions stored in the paHostApiInitializers
54     global array (usually defined in an os-specific pa_[os]_hostapis.c file).
55    
56     This file maintains a list of all open streams and closes them at Pa_Terminate().
57    
58     Some utility functions declared in pa_util.h are implemented in this file.
59    
60     All PortAudio API functions can be conditionally compiled with logging code.
61     To compile with logging, define the PA_LOG_API_CALLS precompiler symbol.
62    
63     @todo Consider adding host API specific error text in Pa_GetErrorText() for
64     paUnanticipatedHostError
65    
66     @todo Consider adding a new error code for when (inputParameters == NULL)
67     && (outputParameters == NULL)
68    
69     @todo review whether Pa_CloseStream() should call the interface's
70     CloseStream function if aborting the stream returns an error code.
71    
72     @todo Create new error codes if a NULL buffer pointer, or a
73     zero frame count is passed to Pa_ReadStream or Pa_WriteStream.
74     */
75    
76    
77     #include <stdio.h>
78     #include <memory.h>
79     #include <string.h>
80     #include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
81    
82     #include "portaudio.h"
83     #include "pa_util.h"
84     #include "pa_endianness.h"
85     #include "pa_types.h"
86     #include "pa_hostapi.h"
87     #include "pa_stream.h"
88     #include "pa_trace.h" /* still usefull?*/
89     #include "pa_debugprint.h"
90    
91    
92     #define PA_VERSION_ 1899
93     #define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")"
94    
95    
96    
97    
98     int Pa_GetVersion( void )
99     {
100     return PA_VERSION_;
101     }
102    
103    
104     const char* Pa_GetVersionText( void )
105     {
106     return PA_VERSION_TEXT_;
107     }
108    
109    
110    
111     #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024
112    
113     static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0};
114    
115     static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ };
116    
117    
118     void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
119     const char *errorText )
120     {
121     lastHostErrorInfo_.hostApiType = hostApiType;
122     lastHostErrorInfo_.errorCode = errorCode;
123    
124     strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ );
125     }
126    
127    
128    
129     static PaUtilHostApiRepresentation **hostApis_ = 0;
130     static int hostApisCount_ = 0;
131     static int initializationCount_ = 0;
132     static int deviceCount_ = 0;
133    
134     PaUtilStreamRepresentation *firstOpenStream_ = NULL;
135    
136    
137     #define PA_IS_INITIALISED_ (initializationCount_ != 0)
138    
139    
140     static int CountHostApiInitializers( void )
141     {
142     int result = 0;
143    
144     while( paHostApiInitializers[ result ] != 0 )
145     ++result;
146     return result;
147     }
148    
149    
150     static void TerminateHostApis( void )
151     {
152     /* terminate in reverse order from initialization */
153     PA_DEBUG(("TerminateHostApis in \n"));
154    
155     while( hostApisCount_ > 0 )
156     {
157     --hostApisCount_;
158     hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );
159     }
160     hostApisCount_ = 0;
161     deviceCount_ = 0;
162    
163     if( hostApis_ != 0 )
164     PaUtil_FreeMemory( hostApis_ );
165     hostApis_ = 0;
166    
167     PA_DEBUG(("TerminateHostApis out\n"));
168     }
169    
170    
171     static PaError InitializeHostApis( void )
172     {
173     PaError result = paNoError;
174     int i, initializerCount, baseDeviceIndex;
175    
176     initializerCount = CountHostApiInitializers();
177    
178     hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
179     sizeof(PaUtilHostApiRepresentation*) * initializerCount );
180     if( !hostApis_ )
181     {
182     result = paInsufficientMemory;
183     goto error;
184     }
185    
186     hostApisCount_ = 0;
187     deviceCount_ = 0;
188     baseDeviceIndex = 0;
189    
190     for( i=0; i< initializerCount; ++i )
191     {
192     hostApis_[hostApisCount_] = NULL;
193    
194     PA_DEBUG(( "before paHostApiInitializers[%d].\n",i));
195    
196     result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
197     if( result != paNoError )
198     goto error;
199    
200     PA_DEBUG(( "after paHostApiInitializers[%d].\n",i));
201    
202     if( hostApis_[hostApisCount_] )
203     {
204     PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];
205     assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
206     assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
207    
208     hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
209    
210     if( hostApi->info.defaultInputDevice != paNoDevice )
211     hostApi->info.defaultInputDevice += baseDeviceIndex;
212    
213     if( hostApi->info.defaultOutputDevice != paNoDevice )
214     hostApi->info.defaultOutputDevice += baseDeviceIndex;
215    
216     baseDeviceIndex += hostApi->info.deviceCount;
217     deviceCount_ += hostApi->info.deviceCount;
218    
219     ++hostApisCount_;
220     }
221     }
222    
223     return result;
224    
225     error:
226     TerminateHostApis();
227     return result;
228     }
229    
230    
231     /*
232     FindHostApi() finds the index of the host api to which
233     <device> belongs and returns it. if <hostSpecificDeviceIndex> is
234     non-null, the host specific device index is returned in it.
235     returns -1 if <device> is out of range.
236    
237     */
238     static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
239     {
240     int i=0;
241    
242     if( !PA_IS_INITIALISED_ )
243     return -1;
244    
245     if( device < 0 )
246     return -1;
247    
248     while( i < hostApisCount_
249     && device >= hostApis_[i]->info.deviceCount )
250     {
251    
252     device -= hostApis_[i]->info.deviceCount;
253     ++i;
254     }
255    
256     if( i >= hostApisCount_ )
257     return -1;
258    
259     if( hostSpecificDeviceIndex )
260     *hostSpecificDeviceIndex = device;
261    
262     return i;
263     }
264    
265    
266     static void AddOpenStream( PaStream* stream )
267     {
268     ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_;
269     firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
270     }
271    
272    
273     static void RemoveOpenStream( PaStream* stream )
274     {
275     PaUtilStreamRepresentation *previous = NULL;
276     PaUtilStreamRepresentation *current = firstOpenStream_;
277    
278     while( current != NULL )
279     {
280     if( ((PaStream*)current) == stream )
281     {
282     if( previous == NULL )
283     {
284     firstOpenStream_ = current->nextOpenStream;
285     }
286     else
287     {
288     previous->nextOpenStream = current->nextOpenStream;
289     }
290     return;
291     }
292     else
293     {
294     previous = current;
295     current = current->nextOpenStream;
296     }
297     }
298     }
299    
300    
301     static void CloseOpenStreams( void )
302     {
303     /* we call Pa_CloseStream() here to ensure that the same destruction
304     logic is used for automatically closed streams */
305    
306     while( firstOpenStream_ != NULL )
307     Pa_CloseStream( firstOpenStream_ );
308     }
309    
310    
311     PaError Pa_Initialize( void )
312     {
313     PaError result;
314    
315     PA_LOGAPI_ENTER( "Pa_Initialize" );
316    
317     if( PA_IS_INITIALISED_ )
318     {
319     ++initializationCount_;
320     result = paNoError;
321     }
322     else
323     {
324     PA_VALIDATE_TYPE_SIZES;
325     PA_VALIDATE_ENDIANNESS;
326    
327     PaUtil_InitializeClock();
328     PaUtil_ResetTraceMessages();
329    
330     result = InitializeHostApis();
331     if( result == paNoError )
332     ++initializationCount_;
333     }
334    
335     PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result );
336    
337     return result;
338     }
339    
340    
341     PaError Pa_Terminate( void )
342     {
343     PaError result;
344    
345     PA_LOGAPI_ENTER( "Pa_Terminate" );
346    
347     if( PA_IS_INITIALISED_ )
348     {
349     if( --initializationCount_ == 0 )
350     {
351     CloseOpenStreams();
352    
353     TerminateHostApis();
354    
355     PaUtil_DumpTraceMessages();
356     }
357     result = paNoError;
358     }
359     else
360     {
361     result= paNotInitialized;
362     }
363    
364     PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result );
365    
366     return result;
367     }
368    
369    
370     const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void )
371     {
372     return &lastHostErrorInfo_;
373     }
374    
375    
376     const char *Pa_GetErrorText( PaError errorCode )
377     {
378     const char *result;
379    
380     switch( errorCode )
381     {
382     case paNoError: result = "Success"; break;
383     case paNotInitialized: result = "PortAudio not initialized"; break;
384     /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError */
385     case paUnanticipatedHostError: result = "Unanticipated host error"; break;
386     case paInvalidChannelCount: result = "Invalid number of channels"; break;
387     case paInvalidSampleRate: result = "Invalid sample rate"; break;
388     case paInvalidDevice: result = "Invalid device"; break;
389     case paInvalidFlag: result = "Invalid flag"; break;
390     case paSampleFormatNotSupported: result = "Sample format not supported"; break;
391     case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break;
392     case paInsufficientMemory: result = "Insufficient memory"; break;
393     case paBufferTooBig: result = "Buffer too big"; break;
394     case paBufferTooSmall: result = "Buffer too small"; break;
395     case paNullCallback: result = "No callback routine specified"; break;
396     case paBadStreamPtr: result = "Invalid stream pointer"; break;
397     case paTimedOut: result = "Wait timed out"; break;
398     case paInternalError: result = "Internal PortAudio error"; break;
399     case paDeviceUnavailable: result = "Device unavailable"; break;
400     case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break;
401     case paStreamIsStopped: result = "Stream is stopped"; break;
402     case paStreamIsNotStopped: result = "Stream is not stopped"; break;
403     case paInputOverflowed: result = "Input overflowed"; break;
404     case paOutputUnderflowed: result = "Output underflowed"; break;
405     case paHostApiNotFound: result = "Host API not found"; break;
406     case paInvalidHostApi: result = "Invalid host API"; break;
407     case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break;
408     case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break;
409     case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break;
410     case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break;
411     case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
412     case paBadBufferPtr: result = "Bad buffer pointer"; break;
413     default:
414     if( errorCode > 0 )
415     result = "Invalid error code (value greater than zero)";
416     else
417     result = "Invalid error code";
418     break;
419     }
420     return result;
421     }
422    
423    
424     PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
425     {
426     PaHostApiIndex result;
427     int i;
428    
429     PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" );
430     PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type ));
431    
432     if( !PA_IS_INITIALISED_ )
433     {
434     result = paNotInitialized;
435     }
436     else
437     {
438     result = paHostApiNotFound;
439    
440     for( i=0; i < hostApisCount_; ++i )
441     {
442     if( hostApis_[i]->info.type == type )
443     {
444     result = i;
445     break;
446     }
447     }
448     }
449    
450     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result );
451    
452     return result;
453     }
454    
455    
456     PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
457     PaHostApiTypeId type )
458     {
459     PaError result;
460     int i;
461    
462     if( !PA_IS_INITIALISED_ )
463     {
464     result = paNotInitialized;
465     }
466     else
467     {
468     result = paHostApiNotFound;
469    
470     for( i=0; i < hostApisCount_; ++i )
471     {
472     if( hostApis_[i]->info.type == type )
473     {
474     *hostApi = hostApis_[i];
475     result = paNoError;
476     break;
477     }
478     }
479     }
480    
481     return result;
482     }
483    
484    
485     PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
486     PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi )
487     {
488     PaError result;
489     PaDeviceIndex x;
490    
491     x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
492    
493     if( x < 0 || x >= hostApi->info.deviceCount )
494     {
495     result = paInvalidDevice;
496     }
497     else
498     {
499     *hostApiDevice = x;
500     result = paNoError;
501     }
502    
503     return result;
504     }
505    
506    
507     PaHostApiIndex Pa_GetHostApiCount( void )
508     {
509     int result;
510    
511     PA_LOGAPI_ENTER( "Pa_GetHostApiCount" );
512    
513     if( !PA_IS_INITIALISED_ )
514     {
515     result = paNotInitialized;
516     }
517     else
518     {
519     result = hostApisCount_;
520     }
521    
522     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result );
523    
524     return result;
525     }
526    
527    
528     PaHostApiIndex Pa_GetDefaultHostApi( void )
529     {
530     int result;
531    
532     PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" );
533    
534     if( !PA_IS_INITIALISED_ )
535     {
536     result = paNotInitialized;
537     }
538     else
539     {
540     result = paDefaultHostApiIndex;
541    
542     /* internal consistency check: make sure that the default host api
543     index is within range */
544    
545     if( result < 0 || result >= hostApisCount_ )
546     {
547     result = paInternalError;
548     }
549     }
550    
551     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result );
552    
553     return result;
554     }
555    
556    
557     const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
558     {
559     PaHostApiInfo *info;
560    
561     PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" );
562     PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi ));
563    
564     if( !PA_IS_INITIALISED_ )
565     {
566     info = NULL;
567    
568     PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
569     PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" ));
570    
571     }
572     else if( hostApi < 0 || hostApi >= hostApisCount_ )
573     {
574     info = NULL;
575    
576     PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
577     PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" ));
578    
579     }
580     else
581     {
582     info = &hostApis_[hostApi]->info;
583    
584     PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
585     PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info ));
586     PA_LOGAPI(("\t{\n" ));
587     PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion ));
588     PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type ));
589     PA_LOGAPI(("\t\tconst char *name: %s\n", info->name ));
590     PA_LOGAPI(("\t}\n" ));
591    
592     }
593    
594     return info;
595     }
596    
597    
598     PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex )
599     {
600     PaDeviceIndex result;
601    
602     PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" );
603     PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi ));
604     PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex ));
605    
606     if( !PA_IS_INITIALISED_ )
607     {
608     result = paNotInitialized;
609     }
610     else
611     {
612     if( hostApi < 0 || hostApi >= hostApisCount_ )
613     {
614     result = paInvalidHostApi;
615     }
616     else
617     {
618     if( hostApiDeviceIndex < 0 ||
619     hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount )
620     {
621     result = paInvalidDevice;
622     }
623     else
624     {
625     result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
626     }
627     }
628     }
629    
630     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result );
631    
632     return result;
633     }
634    
635    
636     PaDeviceIndex Pa_GetDeviceCount( void )
637     {
638     PaDeviceIndex result;
639    
640     PA_LOGAPI_ENTER( "Pa_GetDeviceCount" );
641    
642     if( !PA_IS_INITIALISED_ )
643     {
644     result = paNotInitialized;
645     }
646     else
647     {
648     result = deviceCount_;
649     }
650    
651     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result );
652    
653     return result;
654     }
655    
656    
657     PaDeviceIndex Pa_GetDefaultInputDevice( void )
658     {
659     PaHostApiIndex hostApi;
660     PaDeviceIndex result;
661    
662     PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" );
663    
664     hostApi = Pa_GetDefaultHostApi();
665     if( hostApi < 0 )
666     {
667     result = paNoDevice;
668     }
669     else
670     {
671     result = hostApis_[hostApi]->info.defaultInputDevice;
672     }
673    
674     PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result );
675    
676     return result;
677     }
678    
679    
680     PaDeviceIndex Pa_GetDefaultOutputDevice( void )
681     {
682     PaHostApiIndex hostApi;
683     PaDeviceIndex result;
684    
685     PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" );
686    
687     hostApi = Pa_GetDefaultHostApi();
688     if( hostApi < 0 )
689     {
690     result = paNoDevice;
691     }
692     else
693     {
694     result = hostApis_[hostApi]->info.defaultOutputDevice;
695     }
696    
697     PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result );
698    
699     return result;
700     }
701    
702    
703     const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
704     {
705     int hostSpecificDeviceIndex;
706     int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex );
707     PaDeviceInfo *result;
708    
709    
710     PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" );
711     PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device ));
712    
713     if( hostApiIndex < 0 )
714     {
715     result = NULL;
716    
717     PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" ));
718     PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" ));
719    
720     }
721     else
722     {
723     result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
724    
725     PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" ));
726     PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result ));
727     PA_LOGAPI(("\t{\n" ));
728    
729     PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion ));
730     PA_LOGAPI(("\t\tconst char *name: %s\n", result->name ));
731     PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi ));
732     PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels ));
733     PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels ));
734     PA_LOGAPI(("\t}\n" ));
735    
736     }
737    
738     return result;
739     }
740    
741    
742     /*
743     SampleFormatIsValid() returns 1 if sampleFormat is a sample format
744     defined in portaudio.h, or 0 otherwise.
745     */
746     static int SampleFormatIsValid( PaSampleFormat format )
747     {
748     switch( format & ~paNonInterleaved )
749     {
750     case paFloat32: return 1;
751     case paInt16: return 1;
752     case paInt32: return 1;
753     case paInt24: return 1;
754     case paInt8: return 1;
755     case paUInt8: return 1;
756     case paCustomFormat: return 1;
757     default: return 0;
758     }
759     }
760    
761     /*
762     NOTE: make sure this validation list is kept syncronised with the one in
763     pa_hostapi.h
764    
765     ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
766     conform to the expected values as described below. This function is
767     also designed to be used with the proposed Pa_IsFormatSupported() function.
768    
769     There are basically two types of validation that could be performed:
770     Generic conformance validation, and device capability mismatch
771     validation. This function performs only generic conformance validation.
772     Validation that would require knowledge of device capabilities is
773     not performed because of potentially complex relationships between
774     combinations of parameters - for example, even if the sampleRate
775     seems ok, it might not be for a duplex stream - we have no way of
776     checking this in an API-neutral way, so we don't try.
777    
778     On success the function returns PaNoError and fills in hostApi,
779     hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
780     the function returns an error code indicating the first encountered
781     parameter error.
782    
783    
784     If ValidateOpenStreamParameters() returns paNoError, the following
785     assertions are guaranteed to be true.
786    
787     - at least one of inputParameters & outputParmeters is valid (not NULL)
788    
789     - if inputParameters & outputParameters are both valid, that
790     inputParameters->device & outputParameters->device both use the same host api
791    
792     PaDeviceIndex inputParameters->device
793     - is within range (0 to Pa_GetDeviceCount-1) Or:
794     - is paUseHostApiSpecificDeviceSpecification and
795     inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
796     to a valid host api
797    
798     int inputParameters->channelCount
799     - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
800     - upper bound is NOT validated against device capabilities
801    
802     PaSampleFormat inputParameters->sampleFormat
803     - is one of the sample formats defined in portaudio.h
804    
805     void *inputParameters->hostApiSpecificStreamInfo
806     - if supplied its hostApi field matches the input device's host Api
807    
808     PaDeviceIndex outputParmeters->device
809     - is within range (0 to Pa_GetDeviceCount-1)
810    
811     int outputParmeters->channelCount
812     - if inputDevice is valid, channelCount is > 0
813     - upper bound is NOT validated against device capabilities
814    
815     PaSampleFormat outputParmeters->sampleFormat
816     - is one of the sample formats defined in portaudio.h
817    
818     void *outputParmeters->hostApiSpecificStreamInfo
819     - if supplied its hostApi field matches the output device's host Api
820    
821     double sampleRate
822     - is not an 'absurd' rate (less than 1000. or greater than 200000.)
823     - sampleRate is NOT validated against device capabilities
824    
825     PaStreamFlags streamFlags
826     - unused platform neutral flags are zero
827     - paNeverDropInput is only used for full-duplex callback streams with
828     variable buffer size (paFramesPerBufferUnspecified)
829     */
830     static PaError ValidateOpenStreamParameters(
831     const PaStreamParameters *inputParameters,
832     const PaStreamParameters *outputParameters,
833     double sampleRate,
834     unsigned long framesPerBuffer,
835     PaStreamFlags streamFlags,
836     PaStreamCallback *streamCallback,
837     PaUtilHostApiRepresentation **hostApi,
838     PaDeviceIndex *hostApiInputDevice,
839     PaDeviceIndex *hostApiOutputDevice )
840     {
841     int inputHostApiIndex = -1, /* Surpress uninitialised var warnings: compiler does */
842     outputHostApiIndex = -1; /* not see that if inputParameters and outputParame- */
843     /* ters are both nonzero, these indices are set. */
844    
845     if( (inputParameters == NULL) && (outputParameters == NULL) )
846     {
847     return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */
848     }
849     else
850     {
851     if( inputParameters == NULL )
852     {
853     *hostApiInputDevice = paNoDevice;
854     }
855     else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
856     {
857     if( inputParameters->hostApiSpecificStreamInfo )
858     {
859     inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
860     ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType );
861    
862     if( inputHostApiIndex != -1 )
863     {
864     *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
865     *hostApi = hostApis_[inputHostApiIndex];
866     }
867     else
868     {
869     return paInvalidDevice;
870     }
871     }
872     else
873     {
874     return paInvalidDevice;
875     }
876     }
877     else
878     {
879     if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ )
880     return paInvalidDevice;
881    
882     inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
883     if( inputHostApiIndex < 0 )
884     return paInternalError;
885    
886     *hostApi = hostApis_[inputHostApiIndex];
887    
888     if( inputParameters->channelCount <= 0 )
889     return paInvalidChannelCount;
890    
891     if( !SampleFormatIsValid( inputParameters->sampleFormat ) )
892     return paSampleFormatNotSupported;
893    
894     if( inputParameters->hostApiSpecificStreamInfo != NULL )
895     {
896     if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType
897     != (*hostApi)->info.type )
898     return paIncompatibleHostApiSpecificStreamInfo;
899     }
900     }
901    
902     if( outputParameters == NULL )
903     {
904     *hostApiOutputDevice = paNoDevice;
905     }
906     else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
907     {
908     if( outputParameters->hostApiSpecificStreamInfo )
909     {
910     outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
911     ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType );
912    
913     if( outputHostApiIndex != -1 )
914     {
915     *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
916     *hostApi = hostApis_[outputHostApiIndex];
917     }
918     else
919     {
920     return paInvalidDevice;
921     }
922     }
923     else
924     {
925     return paInvalidDevice;
926     }
927     }
928     else
929     {
930     if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ )
931     return paInvalidDevice;
932    
933     outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
934     if( outputHostApiIndex < 0 )
935     return paInternalError;
936    
937     *hostApi = hostApis_[outputHostApiIndex];
938    
939     if( outputParameters->channelCount <= 0 )
940     return paInvalidChannelCount;
941    
942     if( !SampleFormatIsValid( outputParameters->sampleFormat ) )
943     return paSampleFormatNotSupported;
944    
945     if( outputParameters->hostApiSpecificStreamInfo != NULL )
946     {
947     if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType
948     != (*hostApi)->info.type )
949     return paIncompatibleHostApiSpecificStreamInfo;
950     }
951     }
952    
953     if( (inputParameters != NULL) && (outputParameters != NULL) )
954     {
955     /* ensure that both devices use the same API */
956     if( inputHostApiIndex != outputHostApiIndex )
957     return paBadIODeviceCombination;
958     }
959     }
960    
961    
962     /* Check for absurd sample rates. */
963     if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
964     return paInvalidSampleRate;
965    
966     if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
967     return paInvalidFlag;
968    
969     if( streamFlags & paNeverDropInput )
970     {
971     /* must be a callback stream */
972     if( !streamCallback )
973     return paInvalidFlag;
974    
975     /* must be a full duplex stream */
976     if( (inputParameters == NULL) || (outputParameters == NULL) )
977     return paInvalidFlag;
978    
979     /* must use paFramesPerBufferUnspecified */
980     if( framesPerBuffer != paFramesPerBufferUnspecified )
981     return paInvalidFlag;
982     }
983    
984     return paNoError;
985     }
986    
987    
988     PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
989     const PaStreamParameters *outputParameters,
990     double sampleRate )
991     {
992     PaError result;
993     PaUtilHostApiRepresentation *hostApi = 0;
994     PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice;
995     PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
996     PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
997    
998    
999     #ifdef PA_LOG_API_CALLS
1000     PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" );
1001    
1002     if( inputParameters == NULL ){
1003     PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" ));
1004     }else{
1005     PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters ));
1006     PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device ));
1007     PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount ));
1008     PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat ));
1009     PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency ));
1010     PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo ));
1011     }
1012    
1013     if( outputParameters == NULL ){
1014     PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" ));
1015     }else{
1016     PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters ));
1017     PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device ));
1018     PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount ));
1019     PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat ));
1020     PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
1021     PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
1022     }
1023    
1024     PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
1025     #endif
1026    
1027     if( !PA_IS_INITIALISED_ )
1028     {
1029     result = paNotInitialized;
1030    
1031     PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
1032     return result;
1033     }
1034    
1035     result = ValidateOpenStreamParameters( inputParameters,
1036     outputParameters,
1037     sampleRate, 0, paNoFlag, 0,
1038     &hostApi,
1039     &hostApiInputDevice,
1040     &hostApiOutputDevice );
1041     if( result != paNoError )
1042     {
1043     PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
1044     return result;
1045     }
1046    
1047    
1048     if( inputParameters )
1049     {
1050     hostApiInputParameters.device = hostApiInputDevice;
1051     hostApiInputParameters.channelCount = inputParameters->channelCount;
1052     hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
1053     hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
1054     hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
1055     hostApiInputParametersPtr = &hostApiInputParameters;
1056     }
1057     else
1058     {
1059     hostApiInputParametersPtr = NULL;
1060     }
1061    
1062     if( outputParameters )
1063     {
1064     hostApiOutputParameters.device = hostApiOutputDevice;
1065     hostApiOutputParameters.channelCount = outputParameters->channelCount;
1066     hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
1067     hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
1068     hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
1069     hostApiOutputParametersPtr = &hostApiOutputParameters;
1070     }
1071     else
1072     {
1073     hostApiOutputParametersPtr = NULL;
1074     }
1075    
1076     result = hostApi->IsFormatSupported( hostApi,
1077     hostApiInputParametersPtr, hostApiOutputParametersPtr,
1078     sampleRate );
1079    
1080     #ifdef PA_LOG_API_CALLS
1081     PA_LOGAPI(("Pa_OpenStream returned:\n" ));
1082     if( result == paFormatIsSupported )
1083     PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" ));
1084     else
1085     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1086     #endif
1087    
1088     return result;
1089     }
1090    
1091    
1092     PaError Pa_OpenStream( PaStream** stream,
1093     const PaStreamParameters *inputParameters,
1094     const PaStreamParameters *outputParameters,
1095     double sampleRate,
1096     unsigned long framesPerBuffer,
1097     PaStreamFlags streamFlags,
1098     PaStreamCallback *streamCallback,
1099     void *userData )
1100     {
1101     PaError result;
1102     PaUtilHostApiRepresentation *hostApi = 0;
1103     PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice;
1104     PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
1105     PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
1106    
1107    
1108     #ifdef PA_LOG_API_CALLS
1109     PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" );
1110     PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));
1111    
1112     if( inputParameters == NULL ){
1113     PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" ));
1114     }else{
1115     PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters ));
1116     PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device ));
1117     PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount ));
1118     PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat ));
1119     PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency ));
1120     PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo ));
1121     }
1122    
1123     if( outputParameters == NULL ){
1124     PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" ));
1125     }else{
1126     PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters ));
1127     PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device ));
1128     PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount ));
1129     PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat ));
1130     PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
1131     PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
1132     }
1133    
1134     PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
1135     PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
1136     PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags ));
1137     PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback ));
1138     PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData ));
1139     #endif
1140    
1141     if( !PA_IS_INITIALISED_ )
1142     {
1143     result = paNotInitialized;
1144    
1145     PA_LOGAPI(("Pa_OpenStream returned:\n" ));
1146     PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
1147     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1148     return result;
1149     }
1150    
1151     /* Check for parameter errors.
1152     NOTE: make sure this validation list is kept syncronised with the one
1153     in pa_hostapi.h
1154     */
1155    
1156     if( stream == NULL )
1157     {
1158     result = paBadStreamPtr;
1159    
1160     PA_LOGAPI(("Pa_OpenStream returned:\n" ));
1161     PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
1162     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1163     return result;
1164     }
1165    
1166     result = ValidateOpenStreamParameters( inputParameters,
1167     outputParameters,
1168     sampleRate, framesPerBuffer,
1169     streamFlags, streamCallback,
1170     &hostApi,
1171     &hostApiInputDevice,
1172     &hostApiOutputDevice );
1173     if( result != paNoError )
1174     {
1175     PA_LOGAPI(("Pa_OpenStream returned:\n" ));
1176     PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
1177     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1178     return result;
1179     }
1180    
1181    
1182     if( inputParameters )
1183     {
1184     hostApiInputParameters.device = hostApiInputDevice;
1185     hostApiInputParameters.channelCount = inputParameters->channelCount;
1186     hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
1187     hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
1188     hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
1189     hostApiInputParametersPtr = &hostApiInputParameters;
1190     }
1191     else
1192     {
1193     hostApiInputParametersPtr = NULL;
1194     }
1195    
1196     if( outputParameters )
1197     {
1198     hostApiOutputParameters.device = hostApiOutputDevice;
1199     hostApiOutputParameters.channelCount = outputParameters->channelCount;
1200     hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
1201     hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
1202     hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
1203     hostApiOutputParametersPtr = &hostApiOutputParameters;
1204     }
1205     else
1206     {
1207     hostApiOutputParametersPtr = NULL;
1208     }
1209    
1210     result = hostApi->OpenStream( hostApi, stream,
1211     hostApiInputParametersPtr, hostApiOutputParametersPtr,
1212     sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
1213    
1214     if( result == paNoError )
1215     AddOpenStream( *stream );
1216    
1217    
1218     PA_LOGAPI(("Pa_OpenStream returned:\n" ));
1219     PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream ));
1220     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1221    
1222     return result;
1223     }
1224    
1225    
1226     PaError Pa_OpenDefaultStream( PaStream** stream,
1227     int inputChannelCount,
1228     int outputChannelCount,
1229     PaSampleFormat sampleFormat,
1230     double sampleRate,
1231     unsigned long framesPerBuffer,
1232     PaStreamCallback *streamCallback,
1233     void *userData )
1234     {
1235     PaError result;
1236     PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
1237     PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
1238    
1239     PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" );
1240     PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));
1241     PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount ));
1242     PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount ));
1243     PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat ));
1244     PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
1245     PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
1246     PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback ));
1247     PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData ));
1248    
1249    
1250     if( inputChannelCount > 0 )
1251     {
1252     hostApiInputParameters.device = Pa_GetDefaultInputDevice();
1253     if( hostApiInputParameters.device == paNoDevice )
1254     return paDeviceUnavailable;
1255    
1256     hostApiInputParameters.channelCount = inputChannelCount;
1257     hostApiInputParameters.sampleFormat = sampleFormat;
1258     /* defaultHighInputLatency is used below instead of
1259     defaultLowInputLatency because it is more important for the default
1260     stream to work reliably than it is for it to work with the lowest
1261     latency.
1262     */
1263     hostApiInputParameters.suggestedLatency =
1264     Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
1265     hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
1266     hostApiInputParametersPtr = &hostApiInputParameters;
1267     }
1268     else
1269     {
1270     hostApiInputParametersPtr = NULL;
1271     }
1272    
1273     if( outputChannelCount > 0 )
1274     {
1275     hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
1276     if( hostApiOutputParameters.device == paNoDevice )
1277     return paDeviceUnavailable;
1278    
1279     hostApiOutputParameters.channelCount = outputChannelCount;
1280     hostApiOutputParameters.sampleFormat = sampleFormat;
1281     /* defaultHighOutputLatency is used below instead of
1282     defaultLowOutputLatency because it is more important for the default
1283     stream to work reliably than it is for it to work with the lowest
1284     latency.
1285     */
1286     hostApiOutputParameters.suggestedLatency =
1287     Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
1288     hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
1289     hostApiOutputParametersPtr = &hostApiOutputParameters;
1290     }
1291     else
1292     {
1293     hostApiOutputParametersPtr = NULL;
1294     }
1295    
1296    
1297     result = Pa_OpenStream(
1298     stream, hostApiInputParametersPtr, hostApiOutputParametersPtr,
1299     sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
1300    
1301     PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" ));
1302     PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream ));
1303     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1304    
1305     return result;
1306     }
1307    
1308    
1309     PaError PaUtil_ValidateStreamPointer( PaStream* stream )
1310     {
1311     if( !PA_IS_INITIALISED_ ) return paNotInitialized;
1312    
1313     if( stream == NULL ) return paBadStreamPtr;
1314    
1315     if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC )
1316     return paBadStreamPtr;
1317    
1318     return paNoError;
1319     }
1320    
1321    
1322     PaError Pa_CloseStream( PaStream* stream )
1323     {
1324     PaUtilStreamInterface *interface;
1325     PaError result = PaUtil_ValidateStreamPointer( stream );
1326    
1327     PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" );
1328     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1329    
1330     /* always remove the open stream from our list, even if this function
1331     eventually returns an error. Otherwise CloseOpenStreams() will
1332     get stuck in an infinite loop */
1333     RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */
1334    
1335     if( result == paNoError )
1336     {
1337     interface = PA_STREAM_INTERFACE(stream);
1338    
1339     /* abort the stream if it isn't stopped */
1340     result = interface->IsStopped( stream );
1341     if( result == 1 )
1342     result = paNoError;
1343     else if( result == 0 )
1344     result = interface->Abort( stream );
1345    
1346     if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? */
1347     result = interface->Close( stream );
1348     }
1349    
1350     PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result );
1351    
1352     return result;
1353     }
1354    
1355    
1356     PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback )
1357     {
1358     PaError result = PaUtil_ValidateStreamPointer( stream );
1359    
1360     PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" );
1361     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1362     PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback ));
1363    
1364     if( result == paNoError )
1365     {
1366     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1367     if( result == 0 )
1368     {
1369     result = paStreamIsNotStopped ;
1370     }
1371     if( result == 1 )
1372     {
1373     PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback;
1374     result = paNoError;
1375     }
1376     }
1377    
1378     PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result );
1379    
1380     return result;
1381    
1382     }
1383    
1384    
1385     PaError Pa_StartStream( PaStream *stream )
1386     {
1387     PaError result = PaUtil_ValidateStreamPointer( stream );
1388    
1389     PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" );
1390     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1391    
1392     if( result == paNoError )
1393     {
1394     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1395     if( result == 0 )
1396     {
1397     result = paStreamIsNotStopped ;
1398     }
1399     else if( result == 1 )
1400     {
1401     result = PA_STREAM_INTERFACE(stream)->Start( stream );
1402     }
1403     }
1404    
1405     PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result );
1406    
1407     return result;
1408     }
1409    
1410    
1411     PaError Pa_StopStream( PaStream *stream )
1412     {
1413     PaError result = PaUtil_ValidateStreamPointer( stream );
1414    
1415     PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" );
1416     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1417    
1418     if( result == paNoError )
1419     {
1420     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1421     if( result == 0 )
1422     {
1423     result = PA_STREAM_INTERFACE(stream)->Stop( stream );
1424     }
1425     else if( result == 1 )
1426     {
1427     result = paStreamIsStopped;
1428     }
1429     }
1430    
1431     PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result );
1432    
1433     return result;
1434     }
1435    
1436    
1437     PaError Pa_AbortStream( PaStream *stream )
1438     {
1439     PaError result = PaUtil_ValidateStreamPointer( stream );
1440    
1441     PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" );
1442     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1443    
1444     if( result == paNoError )
1445     {
1446     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1447     if( result == 0 )
1448     {
1449     result = PA_STREAM_INTERFACE(stream)->Abort( stream );
1450     }
1451     else if( result == 1 )
1452     {
1453     result = paStreamIsStopped;
1454     }
1455     }
1456    
1457     PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result );
1458    
1459     return result;
1460     }
1461    
1462    
1463     PaError Pa_IsStreamStopped( PaStream *stream )
1464     {
1465     PaError result = PaUtil_ValidateStreamPointer( stream );
1466    
1467     PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" );
1468     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1469    
1470     if( result == paNoError )
1471     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1472    
1473     PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result );
1474    
1475     return result;
1476     }
1477    
1478    
1479     PaError Pa_IsStreamActive( PaStream *stream )
1480     {
1481     PaError result = PaUtil_ValidateStreamPointer( stream );
1482    
1483     PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" );
1484     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1485    
1486     if( result == paNoError )
1487     result = PA_STREAM_INTERFACE(stream)->IsActive( stream );
1488    
1489    
1490     PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result );
1491    
1492     return result;
1493     }
1494    
1495    
1496     const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream )
1497     {
1498     PaError error = PaUtil_ValidateStreamPointer( stream );
1499     const PaStreamInfo *result;
1500    
1501     PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" );
1502     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1503    
1504     if( error != paNoError )
1505     {
1506     result = 0;
1507    
1508     PA_LOGAPI(("Pa_GetStreamInfo returned:\n" ));
1509     PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", error, Pa_GetErrorText( error ) ));
1510    
1511     }
1512     else
1513     {
1514     result = &PA_STREAM_REP( stream )->streamInfo;
1515    
1516     PA_LOGAPI(("Pa_GetStreamInfo returned:\n" ));
1517     PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result ));
1518     PA_LOGAPI(("\t{" ));
1519    
1520     PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion ));
1521     PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency ));
1522     PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency ));
1523     PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate ));
1524     PA_LOGAPI(("\t}\n" ));
1525    
1526     }
1527    
1528     return result;
1529     }
1530    
1531    
1532     PaTime Pa_GetStreamTime( PaStream *stream )
1533     {
1534     PaError error = PaUtil_ValidateStreamPointer( stream );
1535     PaTime result;
1536    
1537     PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" );
1538     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1539    
1540     if( error != paNoError )
1541     {
1542     result = 0;
1543    
1544     PA_LOGAPI(("Pa_GetStreamTime returned:\n" ));
1545     PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) ));
1546    
1547     }
1548     else
1549     {
1550     result = PA_STREAM_INTERFACE(stream)->GetTime( stream );
1551    
1552     PA_LOGAPI(("Pa_GetStreamTime returned:\n" ));
1553     PA_LOGAPI(("\tPaTime: %g\n", result ));
1554    
1555     }
1556    
1557     return result;
1558     }
1559    
1560    
1561     double Pa_GetStreamCpuLoad( PaStream* stream )
1562     {
1563     PaError error = PaUtil_ValidateStreamPointer( stream );
1564     double result;
1565    
1566     PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" );
1567     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1568    
1569     if( error != paNoError )
1570     {
1571    
1572     result = 0.0;
1573    
1574     PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" ));
1575     PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) ));
1576    
1577     }
1578     else
1579     {
1580     result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream );
1581    
1582     PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" ));
1583     PA_LOGAPI(("\tdouble: %g\n", result ));
1584    
1585     }
1586    
1587     return result;
1588     }
1589    
1590    
1591     PaError Pa_ReadStream( PaStream* stream,
1592     void *buffer,
1593     unsigned long frames )
1594     {
1595     PaError result = PaUtil_ValidateStreamPointer( stream );
1596    
1597     PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" );
1598     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1599    
1600     if( result == paNoError )
1601     {
1602     if( frames == 0 )
1603     {
1604     /* XXX: Should we not allow the implementation to signal any overflow condition? */
1605     result = paNoError;
1606     }
1607     else if( buffer == 0 )
1608     {
1609     result = paBadBufferPtr;
1610     }
1611     else
1612     {
1613     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1614     if( result == 0 )
1615     {
1616     result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames );
1617     }
1618     else if( result == 1 )
1619     {
1620     result = paStreamIsStopped;
1621     }
1622     }
1623     }
1624    
1625     PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result );
1626    
1627     return result;
1628     }
1629    
1630    
1631     PaError Pa_WriteStream( PaStream* stream,
1632     const void *buffer,
1633     unsigned long frames )
1634     {
1635     PaError result = PaUtil_ValidateStreamPointer( stream );
1636    
1637     PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" );
1638     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1639    
1640     if( result == paNoError )
1641     {
1642     if( frames == 0 )
1643     {
1644     /* XXX: Should we not allow the implementation to signal any underflow condition? */
1645     result = paNoError;
1646     }
1647     else if( buffer == 0 )
1648     {
1649     result = paBadBufferPtr;
1650     }
1651     else
1652     {
1653     result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1654     if( result == 0 )
1655     {
1656     result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames );
1657     }
1658     else if( result == 1 )
1659     {
1660     result = paStreamIsStopped;
1661     }
1662     }
1663     }
1664    
1665     PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result );
1666    
1667     return result;
1668     }
1669    
1670     signed long Pa_GetStreamReadAvailable( PaStream* stream )
1671     {
1672     PaError error = PaUtil_ValidateStreamPointer( stream );
1673     signed long result;
1674    
1675     PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" );
1676     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1677    
1678     if( error != paNoError )
1679     {
1680     result = 0;
1681    
1682     PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" ));
1683     PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) ));
1684    
1685     }
1686     else
1687     {
1688     result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream );
1689    
1690     PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" ));
1691     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1692    
1693     }
1694    
1695     return result;
1696     }
1697    
1698    
1699     signed long Pa_GetStreamWriteAvailable( PaStream* stream )
1700     {
1701     PaError error = PaUtil_ValidateStreamPointer( stream );
1702     signed long result;
1703    
1704     PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" );
1705     PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
1706    
1707     if( error != paNoError )
1708     {
1709     result = 0;
1710    
1711     PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" ));
1712     PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) ));
1713    
1714     }
1715     else
1716     {
1717     result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream );
1718    
1719     PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" ));
1720     PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
1721    
1722     }
1723    
1724     return result;
1725     }
1726    
1727    
1728     PaError Pa_GetSampleSize( PaSampleFormat format )
1729     {
1730     int result;
1731    
1732     PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" );
1733     PA_LOGAPI(("\tPaSampleFormat format: %d\n", format ));
1734    
1735     switch( format & ~paNonInterleaved )
1736     {
1737    
1738     case paUInt8:
1739     case paInt8:
1740     result = 1;
1741     break;
1742    
1743     case paInt16:
1744     result = 2;
1745     break;
1746    
1747     case paInt24:
1748     result = 3;
1749     break;
1750    
1751     case paFloat32:
1752     case paInt32:
1753     result = 4;
1754     break;
1755    
1756     default:
1757     result = paSampleFormatNotSupported;
1758     break;
1759     }
1760    
1761     PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result );
1762    
1763     return (PaError) result;
1764     }
1765    

  ViewVC Help
Powered by ViewVC 1.1.22