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 | |