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 / test / patest_wire.c @ 162:d43aab368df9

History | View | Annotate | Download (11.5 KB)

1
/** @file patest_wire.c
2
        @ingroup test_src
3
        @brief Pass input directly to output.
4

5
        Note that some HW devices, for example many ISA audio cards
6
        on PCs, do NOT support full duplex! For a PC, you normally need
7
        a PCI based audio card such as the SBLive.
8

9
        @author Phil Burk  http://www.softsynth.com
10
    
11
 While adapting to V19-API, I excluded configs with framesPerCallback=0
12
 because of an assert in file pa_common/pa_process.c. Pieter, Oct 9, 2003.
13

14
*/
15
/*
16
 * $Id$
17
 *
18
 * This program uses the PortAudio Portable Audio Library.
19
 * For more information see: http://www.portaudio.com
20
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
21
 *
22
 * Permission is hereby granted, free of charge, to any person obtaining
23
 * a copy of this software and associated documentation files
24
 * (the "Software"), to deal in the Software without restriction,
25
 * including without limitation the rights to use, copy, modify, merge,
26
 * publish, distribute, sublicense, and/or sell copies of the Software,
27
 * and to permit persons to whom the Software is furnished to do so,
28
 * subject to the following conditions:
29
 *
30
 * The above copyright notice and this permission notice shall be
31
 * included in all copies or substantial portions of the Software.
32
 *
33
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
36
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
37
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
38
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
39
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
 */
41

    
42
/*
43
 * The text above constitutes the entire PortAudio license; however, 
44
 * the PortAudio community also makes the following non-binding requests:
45
 *
46
 * Any person wishing to distribute modifications to the Software is
47
 * requested to send the modifications to the original developer so that
48
 * they can be incorporated into the canonical version. It is also 
49
 * requested that these non-binding requests be included along with the 
50
 * license above.
51
 */
52

    
53
#include <stdio.h>
54
#include <math.h>
55
#include "portaudio.h"
56

    
57
#define SAMPLE_RATE            (44100)
58

    
59
typedef struct WireConfig_s
60
{
61
    int isInputInterleaved;
62
    int isOutputInterleaved;
63
    int numInputChannels;
64
    int numOutputChannels;
65
    int framesPerCallback;
66
    /* count status flags */
67
    int numInputUnderflows;
68
    int numInputOverflows;
69
    int numOutputUnderflows;
70
    int numOutputOverflows;
71
    int numPrimingOutputs;
72
    int numCallbacks;
73
} WireConfig_t;
74

    
75
#define USE_FLOAT_INPUT        (1)
76
#define USE_FLOAT_OUTPUT       (1)
77

    
78
/* Latencies set to defaults. */
79

    
80
#if USE_FLOAT_INPUT
81
    #define INPUT_FORMAT  paFloat32
82
    typedef float INPUT_SAMPLE;
83
#else
84
    #define INPUT_FORMAT  paInt16
85
    typedef short INPUT_SAMPLE;
86
#endif
87

    
88
#if USE_FLOAT_OUTPUT
89
    #define OUTPUT_FORMAT  paFloat32
90
    typedef float OUTPUT_SAMPLE;
91
#else
92
    #define OUTPUT_FORMAT  paInt16
93
    typedef short OUTPUT_SAMPLE;
94
#endif
95

    
96
double gInOutScaler = 1.0;
97
#define CONVERT_IN_TO_OUT(in)  ((OUTPUT_SAMPLE) ((in) * gInOutScaler))
98

    
99
#define INPUT_DEVICE           (Pa_GetDefaultInputDevice())
100
#define OUTPUT_DEVICE          (Pa_GetDefaultOutputDevice())
101

    
102
static PaError TestConfiguration( WireConfig_t *config );
103

    
104
static int wireCallback( const void *inputBuffer, void *outputBuffer,
105
                         unsigned long framesPerBuffer,
106
                         const PaStreamCallbackTimeInfo* timeInfo,
107
                         PaStreamCallbackFlags statusFlags,
108
                         void *userData );
109

    
110
/* This routine will be called by the PortAudio engine when audio is needed.
111
** It may be called at interrupt level on some machines so don't do anything
112
** that could mess up the system like calling malloc() or free().
113
*/
114

    
115
static int wireCallback( const void *inputBuffer, void *outputBuffer,
116
                         unsigned long framesPerBuffer,
117
                         const PaStreamCallbackTimeInfo* timeInfo,
118
                         PaStreamCallbackFlags statusFlags,
119
                         void *userData )
120
{
121
    INPUT_SAMPLE *in;
122
    OUTPUT_SAMPLE *out;
123
    int inStride;
124
    int outStride;
125
    int inDone = 0;
126
    int outDone = 0;
127
    WireConfig_t *config = (WireConfig_t *) userData;
128
    unsigned int i;
129
    int inChannel, outChannel;
130

    
131
    /* This may get called with NULL inputBuffer during initial setup. */
132
    if( inputBuffer == NULL) return 0;
133

    
134
    /* Count flags */
135
    if( (statusFlags & paInputUnderflow) != 0 ) config->numInputUnderflows += 1;
136
    if( (statusFlags & paInputOverflow) != 0 ) config->numInputOverflows += 1;
137
    if( (statusFlags & paOutputUnderflow) != 0 ) config->numOutputUnderflows += 1;
138
    if( (statusFlags & paOutputOverflow) != 0 ) config->numOutputOverflows += 1;
139
    if( (statusFlags & paPrimingOutput) != 0 ) config->numPrimingOutputs += 1;
140
    config->numCallbacks += 1;
141
    
142
    inChannel=0, outChannel=0;
143
    while( !(inDone && outDone) )
144
    {
145
        if( config->isInputInterleaved )
146
        {
147
            in = ((INPUT_SAMPLE*)inputBuffer) + inChannel;
148
            inStride = config->numInputChannels;
149
        }
150
        else
151
        {
152
            in = ((INPUT_SAMPLE**)inputBuffer)[inChannel];
153
            inStride = 1;
154
        }
155

    
156
        if( config->isOutputInterleaved )
157
        {
158
            out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel;
159
            outStride = config->numOutputChannels;
160
        }
161
        else
162
        {
163
            out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel];
164
            outStride = 1;
165
        }
166

    
167
        for( i=0; i<framesPerBuffer; i++ )
168
        {
169
            *out = CONVERT_IN_TO_OUT( *in );
170
            out += outStride;
171
            in += inStride;
172
        }
173

    
174
        if(inChannel < (config->numInputChannels - 1)) inChannel++;
175
        else inDone = 1;
176
        if(outChannel < (config->numOutputChannels - 1)) outChannel++;
177
        else outDone = 1;
178
    }
179
    return 0;
180
}
181

    
182
/*******************************************************************/
183
int main(void);
184
int main(void)
185
{
186
    PaError err = paNoError;
187
    WireConfig_t CONFIG;
188
    WireConfig_t *config = &CONFIG;
189
    int configIndex = 0;;
190

    
191
    err = Pa_Initialize();
192
    if( err != paNoError ) goto error;
193

    
194
    printf("Please connect audio signal to input and listen for it on output!\n");
195
    printf("input format = %lu\n", INPUT_FORMAT );
196
    printf("output format = %lu\n", OUTPUT_FORMAT );
197
    printf("input device ID  = %d\n", INPUT_DEVICE );
198
    printf("output device ID = %d\n", OUTPUT_DEVICE );
199

    
200
    if( INPUT_FORMAT == OUTPUT_FORMAT )
201
    {
202
        gInOutScaler = 1.0;
203
    }
204
    else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) )
205
    {
206
        gInOutScaler = 1.0/32768.0;
207
    }
208
    else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) )
209
    {
210
        gInOutScaler = 32768.0;
211
    }
212

    
213
    for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ )
214
    {
215
        for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ )
216
        {
217
            for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ )
218
            {
219
                for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ )
220
                {
221
                           /* If framesPerCallback = 0, assertion fails in file pa_common/pa_process.c, line 1413: EX. */
222
                    for( config->framesPerCallback = 64; config->framesPerCallback < 129; config->framesPerCallback += 64 )
223
                    {
224
                        printf("-----------------------------------------------\n" );
225
                        printf("Configuration #%d\n", configIndex++ );
226
                        err = TestConfiguration( config );
227
                        /* Give user a chance to bail out. */
228
                        if( err == 1 )
229
                        {
230
                            err = paNoError;
231
                            goto done;
232
                        }
233
                        else if( err != paNoError ) goto error;
234
                    }
235
               }
236
            }
237
        }
238
    }
239

    
240
done:
241
    Pa_Terminate();
242
    printf("Full duplex sound test complete.\n"); fflush(stdout);
243
    printf("Hit ENTER to quit.\n");  fflush(stdout);
244
    getchar();
245
    return 0;
246

    
247
error:
248
    Pa_Terminate();
249
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
250
    fprintf( stderr, "Error number: %d\n", err );
251
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
252
    printf("Hit ENTER to quit.\n");  fflush(stdout);
253
    getchar();
254
    return -1;
255
}
256

    
257
static PaError TestConfiguration( WireConfig_t *config )
258
{
259
    int c;
260
    PaError err = paNoError;
261
    PaStream *stream;
262
    PaStreamParameters inputParameters, outputParameters;
263
    
264
    printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") );
265
    printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") );
266
    printf("input channels = %d\n", config->numInputChannels );
267
    printf("output channels = %d\n", config->numOutputChannels );
268
    printf("framesPerCallback = %d\n", config->framesPerCallback );
269

    
270
    inputParameters.device = INPUT_DEVICE;              /* default input device */
271
    if (inputParameters.device == paNoDevice) {
272
        fprintf(stderr,"Error: No default input device.\n");
273
        goto error;
274
    }
275
    inputParameters.channelCount = config->numInputChannels;
276
    inputParameters.sampleFormat = INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved);
277
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
278
    inputParameters.hostApiSpecificStreamInfo = NULL;
279

    
280
    outputParameters.device = OUTPUT_DEVICE;            /* default output device */
281
    if (outputParameters.device == paNoDevice) {
282
        fprintf(stderr,"Error: No default output device.\n");
283
        goto error;
284
    }
285
    outputParameters.channelCount = config->numOutputChannels;
286
    outputParameters.sampleFormat = OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved);
287
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
288
    outputParameters.hostApiSpecificStreamInfo = NULL;
289

    
290
    config->numInputUnderflows = 0;
291
    config->numInputOverflows = 0;
292
    config->numOutputUnderflows = 0;
293
    config->numOutputOverflows = 0;
294
    config->numPrimingOutputs = 0;
295
    config->numCallbacks = 0;
296

    
297
    err = Pa_OpenStream(
298
              &stream,
299
              &inputParameters,
300
              &outputParameters,
301
              SAMPLE_RATE,
302
              config->framesPerCallback, /* frames per buffer */
303
              paClipOff, /* we won't output out of range samples so don't bother clipping them */
304
              wireCallback,
305
              config );
306
    if( err != paNoError ) goto error;
307
    
308
    err = Pa_StartStream( stream );
309
    if( err != paNoError ) goto error;
310
    
311
    printf("Now recording and playing. - Hit ENTER for next configuration, or 'q' to quit.\n");  fflush(stdout);
312
    c = getchar();
313
    
314
    printf("Closing stream.\n");
315
    err = Pa_CloseStream( stream );
316
    if( err != paNoError ) goto error;
317

    
318
#define CHECK_FLAG_COUNT(member) \
319
    if( config->member > 0 ) printf("FLAGS SET: " #member " = %d\n", config->member );
320
    CHECK_FLAG_COUNT( numInputUnderflows );
321
    CHECK_FLAG_COUNT( numInputOverflows );
322
    CHECK_FLAG_COUNT( numOutputUnderflows );
323
    CHECK_FLAG_COUNT( numOutputOverflows );
324
    CHECK_FLAG_COUNT( numPrimingOutputs );
325
    printf("number of callbacks = %d\n", config->numCallbacks );
326

    
327
    if( c == 'q' ) return 1;
328

    
329
error:
330
    return err;
331
}