10961097
1
/** @file patest_read_write_wire.c
1
/** @file patest_read_write_wire.c
2
    @brief Tests full duplex blocking I/O by passing input straight to output.
2
    @ingroup test_src
3
    @author Bjorn Roche. XO Audio LLC for Z-Systems Engineering.
3
    @brief Tests full duplex blocking I/O by passing input straight to output.
4
    @author based on code by: Phil Burk  http://www.softsynth.com
4
    @author Bjorn Roche. XO Audio LLC for Z-Systems Engineering.
5
    @author based on code by: Ross Bencina rossb@audiomulch.com
5
    @author based on code by: Phil Burk  http://www.softsynth.com
6
*/
6
    @author based on code by: Ross Bencina rossb@audiomulch.com
7
/*
7
*/
8
 * $Id: patest_read_record.c 757 2004-02-13 07:48:10Z rossbencina $
8
/*
9
 *
9
 * $Id: patest_read_record.c 757 2004-02-13 07:48:10Z rossbencina $
10
 * This program uses the PortAudio Portable Audio Library.
10
 *
11
 * For more information see: http://www.portaudio.com
11
 * This program uses the PortAudio Portable Audio Library.
12
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
12
 * For more information see: http://www.portaudio.com
13
 *
13
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
 
 
14
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining
15
 * Permission is hereby granted, free of charge, to any person obtaining
15
 * a copy of this software and associated documentation files
16
 * a copy of this software and associated documentation files
16
 * (the "Software"), to deal in the Software without restriction,
17
 * (the "Software"), to deal in the Software without restriction,
...
 
...
 
40
 * they can be incorporated into the canonical version. It is also 
41
 * they can be incorporated into the canonical version. It is also 
41
 * requested that these non-binding requests be included along with the 
42
 * requested that these non-binding requests be included along with the 
42
 * license above.
43
 * license above.
43
 */
44
 */
44
 
45
 
45
#include <stdio.h>
46
#include <stdio.h>
46
#include <stdlib.h>
47
#include <stdlib.h>
47
#include "portaudio.h"
48
#include "portaudio.h"
48
 
49
 
49
/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
50
/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
50
#define SAMPLE_RATE  (44100)
51
#define SAMPLE_RATE  (44100)
51
#define FRAMES_PER_BUFFER (1024)
52
#define FRAMES_PER_BUFFER (1024)
52
#define NUM_CHANNELS    (2)
53
#define NUM_CHANNELS    (2)
53
/* #define DITHER_FLAG     (paDitherOff)  */
54
/* #define DITHER_FLAG     (paDitherOff)  */
54
#define DITHER_FLAG     (0) /**/
55
#define DITHER_FLAG     (0) /**/
55
 
56
 
56
/* Select sample format. */
57
/* Select sample format. */
57
#if 1
58
#if 1
58
#define PA_SAMPLE_TYPE  paFloat32
59
#define PA_SAMPLE_TYPE  paFloat32
59
typedef float SAMPLE;
60
typedef float SAMPLE;
60
#define SAMPLE_SILENCE  (0.0f)
61
#define SAMPLE_SILENCE  (0.0f)
61
#define PRINTF_S_FORMAT "%.8f"
62
#define PRINTF_S_FORMAT "%.8f"
62
#elif 1
63
#elif 1
63
#define PA_SAMPLE_TYPE  paInt16
64
#define PA_SAMPLE_TYPE  paInt16
64
typedef short SAMPLE;
65
typedef short SAMPLE;
65
#define SAMPLE_SILENCE  (0)
66
#define SAMPLE_SILENCE  (0)
66
#define PRINTF_S_FORMAT "%d"
67
#define PRINTF_S_FORMAT "%d"
67
#elif 0
68
#elif 0
68
#define PA_SAMPLE_TYPE  paInt8
69
#define PA_SAMPLE_TYPE  paInt8
69
typedef char SAMPLE;
70
typedef char SAMPLE;
70
#define SAMPLE_SILENCE  (0)
71
#define SAMPLE_SILENCE  (0)
71
#define PRINTF_S_FORMAT "%d"
72
#define PRINTF_S_FORMAT "%d"
72
#else
73
#else
73
#define PA_SAMPLE_TYPE  paUInt8
74
#define PA_SAMPLE_TYPE  paUInt8
74
typedef unsigned char SAMPLE;
75
typedef unsigned char SAMPLE;
75
#define SAMPLE_SILENCE  (128)
76
#define SAMPLE_SILENCE  (128)
76
#define PRINTF_S_FORMAT "%d"
77
#define PRINTF_S_FORMAT "%d"
77
#endif
78
#endif
78
 
79
 
79
 
80
 
80
/*******************************************************************/
81
/*******************************************************************/
81
int main(void);
82
int main(void);
82
int main(void)
83
int main(void)
83
{
84
{
84
    PaStreamParameters inputParameters, outputParameters;
85
    PaStreamParameters inputParameters, outputParameters;
85
    PaStream *stream = NULL;
86
    PaStream *stream = NULL;
86
    PaError err;
87
    PaError err;
87
    SAMPLE *sampleBlock;
88
    SAMPLE *sampleBlock;
88
    int i;
89
    int i;
89
    int numBytes;
90
    int numBytes;
90
 
91
 
91
 
92
 
92
    printf("patest_read_write_wire.c\n"); fflush(stdout);
93
    printf("patest_read_write_wire.c\n"); fflush(stdout);
93
 
94
 
94
    numBytes = FRAMES_PER_BUFFER * NUM_CHANNELS * sizeof(SAMPLE);
95
    numBytes = FRAMES_PER_BUFFER * NUM_CHANNELS * sizeof(SAMPLE);
95
    sampleBlock = (SAMPLE *) malloc( numBytes );
96
    sampleBlock = (SAMPLE *) malloc( numBytes );
96
    if( sampleBlock == NULL )
97
    if( sampleBlock == NULL )
97
    {
98
    {
98
        printf("Could not allocate record array.\n");
99
        printf("Could not allocate record array.\n");
99
        exit(1);
100
        exit(1);
100
    }
101
    }
101
    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
102
    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
102
        sampleBlock[i] = (SAMPLE_SILENCE);
103
        sampleBlock[i] = (SAMPLE_SILENCE);
103
 
104
 
104
    err = Pa_Initialize();
105
    err = Pa_Initialize();
105
    if( err != paNoError ) goto error;
106
    if( err != paNoError ) goto error;
106
 
107
 
107
    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
108
    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
108
    printf( "Input device # %d.\n", inputParameters.device );
109
    printf( "Input device # %d.\n", inputParameters.device );
109
    printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency );
110
    printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency );
110
    printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency );
111
    printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency );
111
    inputParameters.channelCount = NUM_CHANNELS;
112
    inputParameters.channelCount = NUM_CHANNELS;
112
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
113
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
113
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
114
    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
114
    inputParameters.hostApiSpecificStreamInfo = NULL;
115
    inputParameters.hostApiSpecificStreamInfo = NULL;
115
 
116
 
116
    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
117
    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
117
    printf( "Output device # %d.\n", outputParameters.device );
118
    printf( "Output device # %d.\n", outputParameters.device );
118
    printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
119
    printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
119
    printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
120
    printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
120
    outputParameters.channelCount = NUM_CHANNELS;
121
    outputParameters.channelCount = NUM_CHANNELS;
121
    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
122
    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
122
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
123
    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
123
    outputParameters.hostApiSpecificStreamInfo = NULL;
124
    outputParameters.hostApiSpecificStreamInfo = NULL;
124
 
125
 
125
    /* -- setup -- */
126
    /* -- setup -- */
126
 
127
 
127
   err = Pa_OpenStream(
128
   err = Pa_OpenStream(
128
              &stream,
129
              &stream,
129
              &inputParameters,
130
              &inputParameters,
130
              &outputParameters,
131
              &outputParameters,
131
              SAMPLE_RATE,
132
              SAMPLE_RATE,
132
              FRAMES_PER_BUFFER,
133
              FRAMES_PER_BUFFER,
133
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
134
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
134
              NULL, /* no callback, use blocking API */
135
              NULL, /* no callback, use blocking API */
135
              NULL ); /* no callback, so no callback userData */
136
              NULL ); /* no callback, so no callback userData */
136
    if( err != paNoError ) goto error;
137
    if( err != paNoError ) goto error;
137
 
138
 
138
    err = Pa_StartStream( stream );
139
    err = Pa_StartStream( stream );
139
    if( err != paNoError ) goto error;
140
    if( err != paNoError ) goto error;
140
    printf("Wire on. Will run one minute.\n"); fflush(stdout);
141
    printf("Wire on. Will run one minute.\n"); fflush(stdout);
141
 
142
 
142
    for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
143
    for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
143
    {
144
    {
144
       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
145
       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
145
       if( err ) goto xrun;
146
       if( err ) goto xrun;
146
       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
147
       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
147
       if( err ) goto xrun;
148
       if( err ) goto xrun;
148
    }
149
    }
149
    err = Pa_StopStream( stream );
150
    err = Pa_StopStream( stream );
150
    if( err != paNoError ) goto error;
151
    if( err != paNoError ) goto error;
151
 
152
 
152
    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
153
    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
153
        sampleBlock[i] = (SAMPLE_SILENCE);
154
        sampleBlock[i] = (SAMPLE_SILENCE);
154
 
155
 
155
    err = Pa_StartStream( stream );
156
    err = Pa_StartStream( stream );
156
    if( err != paNoError ) goto error;
157
    if( err != paNoError ) goto error;
157
    printf("Wire on. Interrupt to stop.\n"); fflush(stdout);
158
    printf("Wire on. Interrupt to stop.\n"); fflush(stdout);
158
 
159
 
159
    while( 1 )
160
    while( 1 )
160
    {
161
    {
161
       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
162
       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
162
       if( err ) goto xrun;
163
       if( err ) goto xrun;
163
       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
164
       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
164
       if( err ) goto xrun;
165
       if( err ) goto xrun;
165
    }
166
    }
166
    err = Pa_StopStream( stream );
167
    err = Pa_StopStream( stream );
167
    if( err != paNoError ) goto error;
168
    if( err != paNoError ) goto error;
168
 
169
 
169
    Pa_CloseStream( stream );
170
    Pa_CloseStream( stream );
170
 
171
 
171
    free( sampleBlock );
172
    free( sampleBlock );
172
 
173
 
173
    Pa_Terminate();
174
    Pa_Terminate();
174
    return 0;
175
    return 0;
175
 
176
 
176
xrun:
177
xrun:
177
    if( stream ) {
178
    if( stream ) {
178
       Pa_AbortStream( stream );
179
       Pa_AbortStream( stream );
179
       Pa_CloseStream( stream );
180
       Pa_CloseStream( stream );
180
    }
181
    }
181
    free( sampleBlock );
182
    free( sampleBlock );
182
    Pa_Terminate();
183
    Pa_Terminate();
183
    if( err & paInputOverflow )
184
    if( err & paInputOverflow )
184
       fprintf( stderr, "Input Overflow.\n" );
185
       fprintf( stderr, "Input Overflow.\n" );
185
    if( err & paOutputUnderflow )
186
    if( err & paOutputUnderflow )
186
       fprintf( stderr, "Output Underflow.\n" );
187
       fprintf( stderr, "Output Underflow.\n" );
187
    return -2;
188
    return -2;
188
 
189
 
189
error:
190
error:
190
    if( stream ) {
191
    if( stream ) {
191
       Pa_AbortStream( stream );
192
       Pa_AbortStream( stream );
192
       Pa_CloseStream( stream );
193
       Pa_CloseStream( stream );
193
    }
194
    }
194
    free( sampleBlock );
195
    free( sampleBlock );
195
    Pa_Terminate();
196
    Pa_Terminate();
196
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
197
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
197
    fprintf( stderr, "Error number: %d\n", err );
198
    fprintf( stderr, "Error number: %d\n", err );
198
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
199
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
199
    return -1;
200
    return -1;
200
}
201
}
201
 
202