To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / qa / paqa_errs.c @ 164:9fa11135915a

History | View | Annotate | Download (18.3 KB)

1
/** @file paqa_errs.c
2
        @ingroup qa_src
3
        @brief Self Testing Quality Assurance app for PortAudio
4
        Do lots of bad things to test error reporting.
5
        @author Phil Burk  http://www.softsynth.com
6
    Pieter Suurmond adapted to V19 API.
7
*/
8
/*
9
 * $Id$
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
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
30
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
 */
34

    
35
/*
36
 * The text above constitutes the entire PortAudio license; however, 
37
 * the PortAudio community also makes the following non-binding requests:
38
 *
39
 * Any person wishing to distribute modifications to the Software is
40
 * requested to send the modifications to the original developer so that
41
 * they can be incorporated into the canonical version. It is also 
42
 * requested that these non-binding requests be included along with the 
43
 * license above.
44
 */
45
 
46
#include <stdio.h>
47
#include <math.h>
48

    
49
#include "portaudio.h"
50

    
51
/*--------- Definitions ---------*/
52
#define MODE_INPUT        (0)
53
#define MODE_OUTPUT       (1)
54
#define FRAMES_PER_BUFFER (64)
55
#define SAMPLE_RATE       (44100.0)
56

    
57
typedef struct PaQaData
58
{
59
    unsigned long  framesLeft;
60
    int            numChannels;
61
    int            bytesPerSample;
62
    int            mode;
63
}
64
PaQaData;
65

    
66
static int gNumPassed = 0; /* Two globals */
67
static int gNumFailed = 0;
68

    
69
/*------------------- Macros ------------------------------*/
70
/* Print ERROR if it fails. Tally success or failure. Odd  */
71
/* do-while wrapper seems to be needed for some compilers. */
72

    
73
#define EXPECT(_exp) \
74
    do \
75
    { \
76
        if ((_exp)) {\
77
            gNumPassed++; \
78
        } \
79
        else { \
80
            printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
81
            gNumFailed++; \
82
            goto error; \
83
        } \
84
    } while(0)
85

    
86
#define HOPEFOR(_exp) \
87
    do \
88
    { \
89
        if ((_exp)) {\
90
            gNumPassed++; \
91
        } \
92
        else { \
93
            printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
94
            gNumFailed++; \
95
        } \
96
    } while(0)
97

    
98
/*-------------------------------------------------------------------------*/
99
/* This routine will be called by the PortAudio engine when audio is needed.
100
   It may be called at interrupt level on some machines so don't do anything
101
   that could mess up the system like calling malloc() or free().
102
*/
103
static int QaCallback( const void*                      inputBuffer,
104
                       void*                            outputBuffer,
105
                       unsigned long                    framesPerBuffer,
106
                                   const PaStreamCallbackTimeInfo*  timeInfo,
107
                                   PaStreamCallbackFlags            statusFlags,
108
                       void*                            userData )
109
{
110
    unsigned long   i;
111
    unsigned char*  out = (unsigned char *) outputBuffer;
112
    PaQaData*       data = (PaQaData *) userData;
113
    
114
    (void)inputBuffer; /* Prevent "unused variable" warnings. */
115

    
116
    /* Zero out buffer so we don't hear terrible noise. */
117
    if( data->mode == MODE_OUTPUT )
118
    {
119
        unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample;
120
        for( i=0; i<numBytes; i++ )
121
        {
122
            *out++ = 0;
123
        }
124
    }
125
    /* Are we through yet? */
126
    if( data->framesLeft > framesPerBuffer )
127
    {
128
        data->framesLeft -= framesPerBuffer;
129
        return 0;
130
    }
131
    else
132
    {
133
        data->framesLeft = 0;
134
        return 1;
135
    }
136
}
137

    
138
static PaDeviceIndex FindInputOnlyDevice(void)
139
{
140
    PaDeviceIndex result = Pa_GetDefaultInputDevice();
141
    if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
142
        return result;
143

    
144
    for( result = 0; result < Pa_GetDeviceCount(); ++result )
145
    {
146
        if( Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
147
            return result;
148
    }
149

    
150
    return paNoDevice;
151
}
152

    
153
static PaDeviceIndex FindOutputOnlyDevice(void)
154
{
155
    PaDeviceIndex result = Pa_GetDefaultOutputDevice();
156
    if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
157
        return result;
158

    
159
    for( result = 0; result < Pa_GetDeviceCount(); ++result )
160
    {
161
        if( Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
162
            return result;
163
    }
164

    
165
    return paNoDevice;
166
}
167

    
168
/*-------------------------------------------------------------------------------------------------*/
169
static int TestBadOpens( void )
170
{
171
    PaStream*           stream = NULL;
172
    PaError             result;
173
    PaQaData            myData;
174
    PaStreamParameters  ipp, opp;
175
    const PaDeviceInfo* info = NULL;
176

    
177
    
178
    /* Setup data for synthesis thread. */
179
    myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */
180
    myData.numChannels = 1;
181
    myData.mode = MODE_OUTPUT;
182

    
183
    /*----------------------------- No devices specified: */
184
    ipp.device                    = opp.device                    = paNoDevice;
185
    ipp.channelCount              = opp.channelCount              = 0; /* Also no channels. */
186
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
187
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
188
    /* Take the low latency of the default device for all subsequent tests. */
189
    info = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
190
    ipp.suggestedLatency          = info ? info->defaultLowInputLatency : 0.100;
191
    info = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
192
    opp.suggestedLatency          = info ? info->defaultLowOutputLatency : 0.100;
193
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
194
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
195
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
196

    
197
    /*----------------------------- No devices specified #2: */
198
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, NULL,
199
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
200
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
201

    
202
    /*----------------------------- Out of range input device specified: */
203
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
204
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
205
    ipp.channelCount = 0;           ipp.device = Pa_GetDeviceCount(); /* And no output device, and no channels. */
206
    opp.channelCount = 0;           opp.device = paNoDevice;
207
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
208
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
209
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
210

    
211
    /*----------------------------- Out of range output device specified: */
212
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
213
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
214
    ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
215
    opp.channelCount = 0;           opp.device = Pa_GetDeviceCount();
216
    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
217
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
218
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
219

    
220
    if (Pa_GetDefaultInputDevice() != paNoDevice) {
221
        /*----------------------------- Zero input channels: */
222
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
223
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
224
        ipp.channelCount = 0;           ipp.device = Pa_GetDefaultInputDevice();
225
        opp.channelCount = 0;           opp.device = paNoDevice;    /* And no output device, and no output channels. */   
226
        HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
227
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
228
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
229
    }
230

    
231
    if (Pa_GetDefaultOutputDevice() != paNoDevice) {
232
        /*----------------------------- Zero output channels: */
233
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
234
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
235
        ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no input channels. */
236
        opp.channelCount = 0;           opp.device = Pa_GetDefaultOutputDevice();
237
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
238
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
239
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
240
    }
241
    /*----------------------------- Nonzero input and output channels but no output device: */
242
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
243
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
244
    ipp.channelCount = 2;           ipp.device = Pa_GetDefaultInputDevice();        /* Both stereo. */
245
    opp.channelCount = 2;           opp.device = paNoDevice;
246
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
247
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
248
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
249

    
250
    /*----------------------------- Nonzero input and output channels but no input device: */
251
    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
252
    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
253
    ipp.channelCount = 2;           ipp.device = paNoDevice;
254
    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
255
    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
256
                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
257
                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
258

    
259
    if (Pa_GetDefaultOutputDevice() != paNoDevice) {
260
        /*----------------------------- NULL stream pointer: */
261
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
262
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
263
        ipp.channelCount = 0;           ipp.device = paNoDevice;           /* Output is more likely than input. */
264
        opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();    /* Only 2 output channels. */
265
        HOPEFOR(((result = Pa_OpenStream(NULL, &ipp, &opp,
266
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
267
                                         paClipOff, QaCallback, &myData )) == paBadStreamPtr));
268

    
269
        /*----------------------------- Low sample rate: */
270
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
271
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
272
        ipp.channelCount = 0;           ipp.device = paNoDevice;
273
        opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
274
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
275
                                         1.0, FRAMES_PER_BUFFER, /* 1 cycle per second (1 Hz) is too low. */
276
                                         paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
277
        
278
        /*----------------------------- High sample rate: */
279
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
280
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
281
        ipp.channelCount = 0;           ipp.device = paNoDevice;
282
        opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
283
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
284
                                         10000000.0, FRAMES_PER_BUFFER, /* 10^6 cycles per second (10 MHz) is too high. */
285
                                         paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
286

    
287
        /*----------------------------- NULL callback: */
288
        /* NULL callback is valid in V19 -- it means use blocking read/write stream
289
    
290
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
291
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
292
        ipp.channelCount = 0;           ipp.device = paNoDevice;
293
        opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
294
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
295
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
296
                                         paClipOff,
297
                                         NULL,
298
                                         &myData )) == paNullCallback));
299
        */
300

    
301
        /*----------------------------- Bad flag: */
302
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
303
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
304
        ipp.channelCount = 0;           ipp.device = paNoDevice;
305
        opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
306
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
307
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
308
                                         255,                      /* Is 8 maybe legal V19 API? */
309
                                         QaCallback, &myData )) == paInvalidFlag));
310
    }
311

    
312
    /*----------------------------- using input device as output device: */
313
    if( FindInputOnlyDevice() != paNoDevice )
314
    {
315
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
316
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
317
        ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
318
        opp.channelCount = 2;           opp.device = FindInputOnlyDevice();
319
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
320
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
321
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
322
    }
323

    
324
    /*----------------------------- using output device as input device: */
325
    if( FindOutputOnlyDevice() != paNoDevice )
326
    {
327
        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
328
        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
329
        ipp.channelCount = 2;           ipp.device = FindOutputOnlyDevice();
330
        opp.channelCount = 0;           opp.device = paNoDevice;  /* And no output device, and no channels. */
331
        HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
332
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
333
                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
334

    
335
    }
336

    
337
    if( stream != NULL ) Pa_CloseStream( stream );
338
    return result;
339
}
340

    
341
/*-----------------------------------------------------------------------------------------*/
342
static int TestBadActions( void )
343
{
344
    PaStream*           stream = NULL;
345
    const PaDeviceInfo* deviceInfo = NULL;
346
    PaError             result = 0;
347
    PaQaData            myData;
348
    PaStreamParameters  opp;
349
    const PaDeviceInfo* info = NULL;
350

    
351
    /* Setup data for synthesis thread. */
352
    myData.framesLeft = (unsigned long)(SAMPLE_RATE * 100); /* 100 seconds */
353
    myData.numChannels = 1;
354
    myData.mode = MODE_OUTPUT;
355

    
356
    opp.device                    = Pa_GetDefaultOutputDevice(); /* Default output. */
357
    opp.channelCount              = 2;                           /* Stereo output.  */
358
    opp.hostApiSpecificStreamInfo = NULL;
359
    opp.sampleFormat              = paFloat32;
360
    info = Pa_GetDeviceInfo(opp.device);
361
    opp.suggestedLatency          = info ? info->defaultLowOutputLatency : 0.100;
362

    
363
    if (opp.device != paNoDevice) {
364
        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, /* Take NULL as input parame-     */
365
                                         &opp,          /* ters, meaning try only output. */
366
                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
367
                                         paClipOff, QaCallback, &myData )) == paNoError));
368
    }
369
 
370
    HOPEFOR(((deviceInfo = Pa_GetDeviceInfo(paNoDevice))    == NULL));
371
    HOPEFOR(((deviceInfo = Pa_GetDeviceInfo(87654))    == NULL));
372
    HOPEFOR(((result = Pa_StartStream(NULL))    == paBadStreamPtr));
373
    HOPEFOR(((result = Pa_StopStream(NULL))     == paBadStreamPtr));
374
    HOPEFOR(((result = Pa_IsStreamStopped(NULL)) == paBadStreamPtr));
375
    HOPEFOR(((result = Pa_IsStreamActive(NULL)) == paBadStreamPtr));
376
    HOPEFOR(((result = Pa_CloseStream(NULL))    == paBadStreamPtr));
377
    HOPEFOR(((result = Pa_SetStreamFinishedCallback(NULL, NULL)) == paBadStreamPtr));
378
    HOPEFOR(((result = !Pa_GetStreamInfo(NULL))));
379
    HOPEFOR(((result = Pa_GetStreamTime(NULL))  == 0.0));
380
    HOPEFOR(((result = Pa_GetStreamCpuLoad(NULL))  == 0.0));
381
    HOPEFOR(((result = Pa_ReadStream(NULL, NULL, 0))  == paBadStreamPtr));
382
    HOPEFOR(((result = Pa_WriteStream(NULL, NULL, 0))  == paBadStreamPtr));
383

    
384
    /** @todo test Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable */
385

    
386
    if (stream != NULL) Pa_CloseStream(stream);
387
    return result;
388
}
389

    
390
/*---------------------------------------------------------------------*/
391
int main(void);
392
int main(void)
393
{
394
    PaError result;
395
    
396
    EXPECT(((result = Pa_Initialize()) == paNoError));
397
    TestBadOpens();
398
    TestBadActions();
399
error:
400
    Pa_Terminate();
401
    printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed);
402
    return 0;
403
}