portaudio Pa_ReadStream and Pa_WriteStream的使用


使用portaudio 使用Pa_ReadStream and Pa_WriteStream,如下
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include "portaudio.h"
42
43 /* #define SAMPLE_RATE  (17932) /* Test failure to open with this value. */
44 #define SAMPLE_RATE  (44100)
45 #define FRAMES_PER_BUFFER (1024)
46 #define NUM_SECONDS     (5)
47 #define NUM_CHANNELS    (2)
48 /* #define DITHER_FLAG     (paDitherOff)  */
49 #define DITHER_FLAG     (0) /**/
50
51 /* Select sample format. */
52 #if 1
53 #define PA_SAMPLE_TYPE  paFloat32
54 typedef float SAMPLE;
55 #define SAMPLE_SILENCE  (0.0f)
56 #define PRINTF_S_FORMAT "%.8f"
57 #elif 1
58 #define PA_SAMPLE_TYPE  paInt16
59 typedef short SAMPLE;
60 #define SAMPLE_SILENCE  (0)
61 #define PRINTF_S_FORMAT "%d"
62 #elif 0
63 #define PA_SAMPLE_TYPE  paInt8
64 typedef char SAMPLE;
65 #define SAMPLE_SILENCE  (0)
66 #define PRINTF_S_FORMAT "%d"
67 #else
68 #define PA_SAMPLE_TYPE  paUInt8
69 typedef unsigned char SAMPLE;
70 #define SAMPLE_SILENCE  (128)
71 #define PRINTF_S_FORMAT "%d"
72 #endif
73
74 #define FORMATID "fmt "
75 #define DATAID   "data"
76
77 typedef struct {
78   char    chunkID[4];
79   long    chunkSize;
80   short   wFormatTag;
81   unsigned short wChannels;
82   unsigned long dwSamplesPerSec;
83   unsigned long dwAvgBytesPerSec;
84   unsigned short wBlockAlign;
85   unsigned short wBitsPerSample;
86 } FormatChunk;
87
88 typedef struct {
89   char    chunkID[4];
90   long    chunkSize;
91 } DataChunkHeader;
92
93
94
95 int checkHeader(FILE *fid) {
96
97   char riff[4];
98   char wave[4];
99
100   fread(riff, 4, sizeof(char), fid);
101   /* throwaway 4 bytes */
102   fread(wave, 4, sizeof(char), fid);
103   fread(wave, 4, sizeof(char), fid);
104
105   if (!((strncmp(riff, "RIFF", 4) == 0) &&
106        (strncmp(wave, "WAVE", 4) == 0))) {
107     return -1;
108   }
109   
110   return 0;
111 }
112
113
114 int getData(FILE *fid, char **data) {
115
116   DataChunkHeader dch;
117     
118   while (strncmp(dch.chunkID, DATAID, 4) != 0) {
119     fread(&dch, sizeof(DataChunkHeader), 1, fid);
120     if (feof(fid) || ferror(fid))
121       return -1;  
122   }
123
124   printf("Size of data: %d\n", dch.chunkSize);
125
126   *data = (char *) malloc ( dch.chunkSize * sizeof(char) );
127   fread(*data, sizeof(char), dch.chunkSize, fid);
128   if (feof(fid) || ferror(fid)) {
129     free(data);
130     return -1;  
131   }
132
133   return dch.chunkSize;
134 }
135
136 int getFormatChunk(FILE *fid, FormatChunk *formatChunk) {
137   
138   while (strncmp(formatChunk->chunkID, FORMATID, 4) != 0) {
139     fread(formatChunk, sizeof(FormatChunk), 1, fid);
140     if (feof(fid) || ferror(fid))
141       return -1;
142   }
143   return 0;
144 }
145
146
147
148 /*******************************************************************/
149 int main(int argc, char *argv[])
150 {
151     PaStreamParameters outputParameters;
152     PaStream *stream;
153     PaError err;
154     /*int i;
155     int totalFrames;
156     int numSamples;
157     int numBytes;
158     */
159        
160     /* read wave file */
161     char *filename;
162     FILE *fid;
163     
164     if (argc < 2) {
165       printf("Usage: %s filename.wav\n", argv[0]);
166       return -1;
167     }
168     
169     /* filename */
170     filename = argv[1];
171     printf("Filename: %s\n", filename);
172     
173     /* open file */
174     fid = fopen(filename, "rb");
175     if (fid == NULL) {
176       printf("Could not open file %s\n", filename);
177       return -1;
178     }
179     
180     /* check header */
181     if (checkHeader(fid) < 0) {
182       printf("Not a wave file!\n");
183       return -1;
184     }
185     
186     FormatChunk formatChunk;
187     int data_size;
188     char *data;
189
190     if (getFormatChunk(fid, &formatChunk) < 0) {
191       printf("Couldn't read header\n");
192       return -1;
193     }
194     
195     printf("Chunk Size       : %d\n", formatChunk.chunkSize);
196     printf("Compressed       : %d\n", formatChunk.wFormatTag != 1);
197     printf("Channels         : %d\n", formatChunk.wChannels);
198     printf("SamplesPerSecond : %d\n", formatChunk.dwSamplesPerSec);
199     printf("dwAvgBytesPerSec : %d\n", formatChunk.dwAvgBytesPerSec);
200     printf("wBlockAlign      : %d\n", formatChunk.wBlockAlign);
201     printf("wBitsPerSample   : %d\n", formatChunk.wBitsPerSample);
202     
203     if ((data_size = getData(fid, &data)) < 0) {
204       printf("Couldn't read data\n");
205       return -1;
206     }
207     
208     int total_frames = data_size / formatChunk.wBlockAlign;
209
210     printf("Total Frames     : %d\n", total_frames); 
211     /* fclose(fid); */
212
213
214     err = Pa_Initialize();
215     if( err != paNoError ) goto error;
216
217     /* Playback recorded data.  -------------------------------------------- */
218     
219     outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
220
221     outputParameters.channelCount = formatChunk.wChannels;
222     outputParameters.sampleFormat =  paInt16;
223
224     outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
225
226     printf("YO YO\n"); fflush(stdout);
227     outputParameters.hostApiSpecificStreamInfo = NULL;
228
229     printf("Begin playback.\n"); fflush(stdout);
230     err = Pa_OpenStream(
231               &stream,
232               NULL, /* no input */
233               &outputParameters,
234               formatChunk.dwSamplesPerSec,
235               0, /*FRAMES_PER_BUFFER, */
236               paClipOff,      /* we won't output out of range samples so don't bother clipping them */
237               NULL, /* no callback, use blocking API */
238               NULL ); /* no callback, so no callback userData */
239     if( err != paNoError ) goto error;
240
241     if( stream )
242     {
243         err = Pa_StartStream( stream );
244         if( err != paNoError ) goto error;
245         printf("Waiting for playback to finish.\n"); fflush(stdout);
246
247         err = Pa_WriteStream( stream, data, total_frames );
248         if( err != paNoError ) goto error;
249
250         err = Pa_CloseStream( stream );
251         if( err != paNoError ) goto error;
252         printf("Done.\n"); fflush(stdout);
253     }
254     free( data );
255
256     Pa_Terminate();
257     return 0;
258
259 error:
260     Pa_Terminate();
261     fprintf( stderr, "An error occured while using the portaudio stream\n" );
262     fprintf( stderr, "Error number: %d\n", err );
263     fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
264     return -1;
265 }

你可能感兴趣的:(portaudio Pa_ReadStream and Pa_WriteStream的使用)