/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/portaudio/src/common/pa_front.c
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta/3rdparty/portaudio/src/common/pa_front.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (9 years, 5 months ago) by william
File MIME type: text/plain
File size: 54545 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 /*
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