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