1 /** @file pa_devs.c
2     @brief List available devices, including device information.
3 	@author Phil Burk http://www.softsynth.com
4 
5     @note Define PA_NO_ASIO to compile this code on Windows without
6         ASIO support.
7 */
8 /*
9  * $Id: pa_devs.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
10  *
11  * This program uses the PortAudio Portable Audio Library.
12  * For more information see: http://www.portaudio.com
13  * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
14  *
15  * Permission is hereby granted, free of charge, to any person obtaining
16  * a copy of this software and associated documentation files
17  * (the "Software"), to deal in the Software without restriction,
18  * including without limitation the rights to use, copy, modify, merge,
19  * publish, distribute, sublicense, and/or sell copies of the Software,
20  * and to permit persons to whom the Software is furnished to do so,
21  * subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice shall be
24  * included in all copies or substantial portions of the Software.
25  *
26  * Any person wishing to distribute modifications to the Software is
27  * requested to send the modifications to the original developer so that
28  * they can be incorporated into the canonical version.
29  *
30  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
34  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
35  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37  *
38  */
39 #include <stdio.h>
40 #include <math.h>
41 #include "portaudio.h"
42 
43 #ifdef WIN32
44 #ifndef PA_NO_ASIO
45 #include "pa_asio.h"
46 #endif
47 #endif
48 
49 /*******************************************************************/
PrintSupportedStandardSampleRates(const PaStreamParameters * inputParameters,const PaStreamParameters * outputParameters)50 static void PrintSupportedStandardSampleRates(
51         const PaStreamParameters *inputParameters,
52         const PaStreamParameters *outputParameters )
53 {
54     static double standardSampleRates[] = {
55         8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
56         44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated  list */
57     };
58     int     i, printCount;
59     PaError err;
60 
61     printCount = 0;
62     for( i=0; standardSampleRates[i] > 0; i++ )
63     {
64         err = Pa_IsFormatSupported( inputParameters, outputParameters, standardSampleRates[i] );
65         if( err == paFormatIsSupported )
66         {
67             if( printCount == 0 )
68             {
69                 printf( "\t%8.2f", standardSampleRates[i] );
70                 printCount = 1;
71             }
72             else if( printCount == 4 )
73             {
74                 printf( ",\n\t%8.2f", standardSampleRates[i] );
75                 printCount = 1;
76             }
77             else
78             {
79                 printf( ", %8.2f", standardSampleRates[i] );
80                 ++printCount;
81             }
82         }
83     }
84     if( !printCount )
85         printf( "None\n" );
86     else
87         printf( "\n" );
88 }
89 /*******************************************************************/
90 int main(void);
main(void)91 int main(void)
92 {
93     int     i, numDevices, defaultDisplayed;
94     const   PaDeviceInfo *deviceInfo;
95     PaStreamParameters inputParameters, outputParameters;
96     PaError err;
97 
98 
99     Pa_Initialize();
100 
101     printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",
102             Pa_GetVersion(), Pa_GetVersionText() );
103 
104 
105     numDevices = Pa_GetDeviceCount();
106     if( numDevices < 0 )
107     {
108         printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
109         err = numDevices;
110         goto error;
111     }
112 
113     printf( "Number of devices = %d\n", numDevices );
114     for( i=0; i<numDevices; i++ )
115     {
116         deviceInfo = Pa_GetDeviceInfo( i );
117         printf( "--------------------------------------- device #%d\n", i );
118 
119     /* Mark global and API specific default devices */
120         defaultDisplayed = 0;
121         if( i == Pa_GetDefaultInputDevice() )
122         {
123             printf( "[ Default Input" );
124             defaultDisplayed = 1;
125         }
126         else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
127         {
128             const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
129             printf( "[ Default %s Input", hostInfo->name );
130             defaultDisplayed = 1;
131         }
132 
133         if( i == Pa_GetDefaultOutputDevice() )
134         {
135             printf( (defaultDisplayed ? "," : "[") );
136             printf( " Default Output" );
137             defaultDisplayed = 1;
138         }
139         else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
140         {
141             const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
142             printf( (defaultDisplayed ? "," : "[") );
143             printf( " Default %s Output", hostInfo->name );
144             defaultDisplayed = 1;
145         }
146 
147         if( defaultDisplayed )
148             printf( " ]\n" );
149 
150     /* print device info fields */
151         printf( "Name                        = %s\n", deviceInfo->name );
152         printf( "Host API                    = %s\n",  Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
153         printf( "Max inputs = %d", deviceInfo->maxInputChannels  );
154         printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels  );
155 
156         printf( "Default low input latency   = %8.3f\n", deviceInfo->defaultLowInputLatency  );
157         printf( "Default low output latency  = %8.3f\n", deviceInfo->defaultLowOutputLatency  );
158         printf( "Default high input latency  = %8.3f\n", deviceInfo->defaultHighInputLatency  );
159         printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency  );
160 
161 #ifdef WIN32
162 #ifndef PA_NO_ASIO
163 /* ASIO specific latency information */
164         if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){
165             long minLatency, maxLatency, preferredLatency, granularity;
166 
167             err = PaAsio_GetAvailableLatencyValues( i,
168 		            &minLatency, &maxLatency, &preferredLatency, &granularity );
169 
170             printf( "ASIO minimum buffer size    = %ld\n", minLatency  );
171             printf( "ASIO maximum buffer size    = %ld\n", maxLatency  );
172             printf( "ASIO preferred buffer size  = %ld\n", preferredLatency  );
173 
174             if( granularity == -1 )
175                 printf( "ASIO buffer granularity     = power of 2\n" );
176             else
177                 printf( "ASIO buffer granularity     = %ld\n", granularity  );
178         }
179 #endif /* !PA_NO_ASIO */
180 #endif /* WIN32 */
181 
182         printf( "Default sample rate         = %8.2f\n", deviceInfo->defaultSampleRate );
183 
184     /* poll for standard sample rates */
185         inputParameters.device = i;
186         inputParameters.channelCount = deviceInfo->maxInputChannels;
187         inputParameters.sampleFormat = paInt16;
188         inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
189         inputParameters.hostApiSpecificStreamInfo = NULL;
190 
191         outputParameters.device = i;
192         outputParameters.channelCount = deviceInfo->maxOutputChannels;
193         outputParameters.sampleFormat = paInt16;
194         outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
195         outputParameters.hostApiSpecificStreamInfo = NULL;
196 
197         if( inputParameters.channelCount > 0 )
198         {
199             printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n",
200                     inputParameters.channelCount );
201             PrintSupportedStandardSampleRates( &inputParameters, NULL );
202         }
203 
204         if( outputParameters.channelCount > 0 )
205         {
206             printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n",
207                     outputParameters.channelCount );
208             PrintSupportedStandardSampleRates( NULL, &outputParameters );
209         }
210 
211         if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
212         {
213             printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n",
214                     inputParameters.channelCount, outputParameters.channelCount );
215             PrintSupportedStandardSampleRates( &inputParameters, &outputParameters );
216         }
217     }
218 
219     Pa_Terminate();
220 
221     printf("----------------------------------------------\n");
222     return 0;
223 
224 error:
225     Pa_Terminate();
226     fprintf( stderr, "An error occured while using the portaudio stream\n" );
227     fprintf( stderr, "Error number: %d\n", err );
228     fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
229     return err;
230 }
231