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