1 #include <stdio.h>
2 #define MAXDEVICES 100
3 #include <string.h>
4 #include <portaudio.h>
5 #include <QDebug>
6
7 //------------------------------------------------------- pa_get_device_info
pa_get_device_info(int n,void * pa_device_name,void * pa_device_hostapi,double * pa_device_max_speed,double * pa_device_min_speed,int * pa_device_max_bytes,int * pa_device_min_bytes,int * pa_device_max_channels,int * pa_device_min_channels)8 int pa_get_device_info (int n,
9 void *pa_device_name,
10 void *pa_device_hostapi,
11 double *pa_device_max_speed,
12 double *pa_device_min_speed,
13 int *pa_device_max_bytes,
14 int *pa_device_min_bytes,
15 int *pa_device_max_channels,
16 int *pa_device_min_channels )
17 {
18
19 (void) n ;
20 (void) pa_device_name;
21 (void) pa_device_hostapi;
22 (void) pa_device_max_speed;
23 (void) pa_device_min_speed;
24 (void) pa_device_max_bytes;
25 (void) pa_device_min_bytes;
26 (void) pa_device_max_channels;
27 (void) pa_device_min_channels;
28 const PaDeviceInfo *deviceInfo;
29 PaError pa_err;
30 PaStreamParameters inputParameters;
31 int i,j, speed_warning;
32 int minBytes, maxBytes;
33 double maxStandardSampleRate;
34 double minStandardSampleRate;
35 int minInputChannels;
36 int maxInputChannels;
37
38 // negative terminated list
39 static double standardSampleRates[] = {8000.0, 9600.0,
40 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
41 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1};
42 // *******************************************************
43
44
45 *pa_device_max_speed=0;
46 *pa_device_min_speed=0;
47 *pa_device_max_bytes=0;
48 *pa_device_min_bytes=0;
49 *pa_device_max_channels=0;
50 *pa_device_min_channels=0;
51 minInputChannels=0;
52 if(n >= Pa_GetDeviceCount() ) return -1;
53 deviceInfo = Pa_GetDeviceInfo(n);
54 if (deviceInfo->maxInputChannels==0) return -1;
55 sprintf((char*)(pa_device_name),"%s",deviceInfo->name);
56 sprintf((char*)(pa_device_hostapi),"%s",
57 Pa_GetHostApiInfo( deviceInfo->hostApi )->name);
58 speed_warning=0;
59
60 // bypass bug in Juli@ ASIO driver:
61 // this driver hangs after a Pa_IsFormatSupported call
62 i = strncmp(deviceInfo->name, "ASIO 2.0 - ESI Juli@", 19);
63 if (i == 0) {
64 minStandardSampleRate=44100;
65 maxStandardSampleRate=192000;
66 minBytes=1;
67 maxBytes=4;
68 maxInputChannels= deviceInfo->maxInputChannels;
69 minInputChannels= 1;
70 goto end_pa_get_device_info;
71 }
72
73 // Investigate device capabilities.
74 // Check min and max samplerates with 16 bit data.
75 maxStandardSampleRate=0;
76 minStandardSampleRate=0;
77 inputParameters.device = n;
78 inputParameters.channelCount = deviceInfo->maxInputChannels;
79 inputParameters.sampleFormat = paInt16;
80 inputParameters.suggestedLatency = 0;
81 inputParameters.hostApiSpecificStreamInfo = NULL;
82
83 // ************************************************************************
84 //filter for portaudio Windows hostapi's with non experts.
85 //only allow ASIO or WASAPI or WDM-KS
86 i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name, "ASIO", 4);
87 if (i==0 ) goto end_filter_hostapi;
88 i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name,
89 "Windows WASAPI", 14);
90 if (i==0 ) goto end_filter_hostapi;
91 i = strncmp(Pa_GetHostApiInfo(deviceInfo->hostApi)->name,
92 "Windows WDM-KS", 14);
93 if (i==0 ) goto end_filter_hostapi;
94 speed_warning=1;
95 end_filter_hostapi:;
96
97 // ************************************************************************
98 i=0;
99 while(standardSampleRates[i] > 0 && minStandardSampleRate==0) {
100 pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
101 standardSampleRates[i] );
102 if(pa_err == paDeviceUnavailable) return -1;
103 if(pa_err == paInvalidDevice) return -1;
104 if(pa_err == paFormatIsSupported ) {
105 minStandardSampleRate=standardSampleRates[i];
106 }
107 i++;
108 }
109 if(minStandardSampleRate == 0) return -1;
110 j=i;
111 while(standardSampleRates[i] > 0 ) i++;
112 i--;
113
114 while(i >= j && maxStandardSampleRate==0) {
115 pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
116 standardSampleRates[i] );
117 if(pa_err == paDeviceUnavailable) return -1;
118 if(pa_err == paInvalidDevice) return -1;
119 if( pa_err == paFormatIsSupported ) {
120 maxStandardSampleRate=standardSampleRates[i];
121 }
122 i--;
123 }
124
125 // check if min SampleRate = max SampleRate
126 if(maxStandardSampleRate==0 && (minStandardSampleRate != 0)) {
127 maxStandardSampleRate= minStandardSampleRate;
128 }
129
130 // check min and max bytes
131 minBytes=2;
132 maxBytes=2;
133 inputParameters.sampleFormat = paUInt8;
134 pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
135 maxStandardSampleRate );
136 if( pa_err == paFormatIsSupported ) {
137 minBytes=1;
138 }
139 inputParameters.sampleFormat = paInt32;
140 pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
141 maxStandardSampleRate );
142 if( pa_err == paFormatIsSupported ) {
143 maxBytes=4;
144 }
145
146 // check min channel count
147 maxInputChannels= deviceInfo->maxInputChannels;
148 inputParameters.channelCount = 1;
149 inputParameters.sampleFormat = paInt16;
150 pa_err=paFormatIsSupported+32000;
151 while(pa_err != paFormatIsSupported &&
152 ( inputParameters.channelCount < (maxInputChannels+1)) ) {
153 pa_err=Pa_IsFormatSupported(&inputParameters, NULL,
154 maxStandardSampleRate );
155 inputParameters.channelCount++;
156 }
157 if( pa_err == paFormatIsSupported ) {
158 minInputChannels=inputParameters.channelCount-1;
159 } else {
160 return -1;
161 }
162
163 end_pa_get_device_info:;
164
165 *pa_device_max_speed=maxStandardSampleRate;
166 *pa_device_min_speed=minStandardSampleRate;
167 *pa_device_max_bytes=maxBytes;
168 *pa_device_min_bytes=minBytes;
169 *pa_device_max_channels= maxInputChannels;
170 *pa_device_min_channels= minInputChannels;
171
172 return speed_warning;
173 }
174
175
paInputDevice(int id,char * hostAPI_DeviceName,int * minChan,int * maxChan,int * minSpeed,int * maxSpeed)176 void paInputDevice(int id, char* hostAPI_DeviceName, int* minChan,
177 int* maxChan, int* minSpeed, int* maxSpeed)
178 {
179 int i;
180 char pa_device_name[128];
181 char pa_device_hostapi[128];
182 double pa_device_max_speed;
183 double pa_device_min_speed;
184 int pa_device_max_bytes;
185 int pa_device_min_bytes;
186 int pa_device_max_channels;
187 int pa_device_min_channels;
188 char p2[256];
189 char *p,*p1;
190 static int iret, valid_dev_cnt;
191
192 iret=pa_get_device_info (id,
193 &pa_device_name,
194 &pa_device_hostapi,
195 &pa_device_max_speed,
196 &pa_device_min_speed,
197 &pa_device_max_bytes,
198 &pa_device_min_bytes,
199 &pa_device_max_channels,
200 &pa_device_min_channels);
201
202 if (iret >= 0 ) {
203 valid_dev_cnt++;
204
205 p1=(char*)"";
206 p=strstr(pa_device_hostapi,"MME");
207 if(p!=NULL) p1=(char*)"MME";
208 p=strstr(pa_device_hostapi,"Direct");
209 if(p!=NULL) p1=(char*)"DirectX";
210 p=strstr(pa_device_hostapi,"WASAPI");
211 if(p!=NULL) p1=(char*)"WASAPI";
212 p=strstr(pa_device_hostapi,"ASIO");
213 if(p!=NULL) p1=(char*)"ASIO";
214 p=strstr(pa_device_hostapi,"WDM-KS");
215 if(p!=NULL) p1=(char*)"WDM-KS";
216
217 sprintf(p2,"%-8s %-39s",p1,pa_device_name);
218 for(i=0; i<50; i++) {
219 hostAPI_DeviceName[i]=p2[i];
220 if(p2[i]==0) break;
221 }
222 *minChan=pa_device_min_channels;
223 *maxChan=pa_device_max_channels;
224 *minSpeed=(int)pa_device_min_speed;
225 *maxSpeed=(int)pa_device_max_speed;
226 } else {
227 for(i=0; i<50; i++) {
228 hostAPI_DeviceName[i]=0;
229 }
230 *minChan=0;
231 *maxChan=0;
232 *minSpeed=0;
233 *maxSpeed=0;
234 }
235 }
236
getDev(int * numDevices0,char hostAPI_DeviceName[][50],int minChan[],int maxChan[],int minSpeed[],int maxSpeed[])237 void getDev(int* numDevices0, char hostAPI_DeviceName[][50],
238 int minChan[], int maxChan[],
239 int minSpeed[], int maxSpeed[])
240 {
241 int i,id,numDevices;
242 int minch,maxch,minsp,maxsp;
243 char apidev[256];
244
245 numDevices=Pa_GetDeviceCount();
246 *numDevices0=numDevices;
247
248 for(id=0; id<numDevices; id++) {
249 paInputDevice(id,apidev,&minch,&maxch,&minsp,&maxsp);
250 for(i=0; i<50; i++) {
251 hostAPI_DeviceName[id][i]=apidev[i];
252 }
253 hostAPI_DeviceName[id][49]=0;
254 minChan[id]=minch;
255 maxChan[id]=maxch;
256 minSpeed[id]=minsp;
257 maxSpeed[id]=maxsp;
258 }
259 }
260