Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "portaudio.h"
  5.  
  6. /* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
  7. #define SAMPLE_RATE (44100)
  8. #define FRAMES_PER_BUFFER (512)
  9. #define NUM_SECONDS (5)
  10. #define NUM_CHANNELS (2)
  11. /* #define DITHER_FLAG (paDitherOff) */
  12. #define DITHER_FLAG (0)
  13.  
  14. #define WRITE_TO_FILE (0)
  15.  
  16. /* Select sample format. */
  17. #if 1
  18. #define PA_SAMPLE_TYPE paFloat32
  19. typedef float SAMPLE;
  20. #define SAMPLE_SILENCE (0.0f)
  21. #define PRINTF_S_FORMAT "%.8f"
  22. #elif 1
  23. #define PA_SAMPLE_TYPE paInt16
  24. typedef short SAMPLE;
  25. #define SAMPLE_SILENCE (0)
  26. #define PRINTF_S_FORMAT "%d"
  27. #elif 0
  28. #define PA_SAMPLE_TYPE paInt8
  29. typedef char SAMPLE;
  30. #define SAMPLE_SILENCE (0)
  31. #define PRINTF_S_FORMAT "%d"
  32. #else
  33. #define PA_SAMPLE_TYPE paUInt8
  34. typedef unsigned char SAMPLE;
  35. #define SAMPLE_SILENCE (128)
  36. #define PRINTF_S_FORMAT "%d"
  37. #endif
  38.  
  39. typedef struct
  40. {
  41. int frameIndex; /* Index into sample array. */
  42. int maxFrameIndex;
  43. SAMPLE *recordedSamples;
  44. }
  45. paTestData;
  46.  
  47. /* This routine will be called by the PortAudio engine when audio is needed.
  48. ** It may be called at interrupt level on some machines so don't do anything
  49. ** that could mess up the system like calling malloc() or free().
  50. */
  51. static int recordCallback( const void *inputBuffer, void *outputBuffer,
  52. unsigned long framesPerBuffer,
  53. const PaStreamCallbackTimeInfo* timeInfo,
  54. PaStreamCallbackFlags statusFlags,
  55. void *userData )
  56. {
  57. paTestData *data = (paTestData*)userData;
  58. const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
  59. SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
  60. long framesToCalc;
  61. long i;
  62. int finished;
  63. unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
  64.  
  65. (void) outputBuffer; /* Prevent unused variable warnings. */
  66. (void) timeInfo;
  67. (void) statusFlags;
  68. (void) userData;
  69.  
  70. if( framesLeft < framesPerBuffer )
  71. {
  72. framesToCalc = framesLeft;
  73. finished = paComplete;
  74. }
  75. else
  76. {
  77. framesToCalc = framesPerBuffer;
  78. finished = paContinue;
  79. }
  80.  
  81. if( inputBuffer == NULL )
  82. {
  83. for( i=0; i<framesToCalc; i++ )
  84. {
  85. *wptr++ = SAMPLE_SILENCE; /* left */
  86. if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */
  87. }
  88. }
  89. else
  90. {
  91. for( i=0; i<framesToCalc; i++ )
  92. {
  93. *wptr++ = *rptr++; /* left */
  94. if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
  95. }
  96. }
  97. data->frameIndex += framesToCalc;
  98. return finished;
  99. }
  100.  
  101. /* This routine will be called by the PortAudio engine when audio is needed.
  102. ** It may be called at interrupt level on some machines so don't do anything
  103. ** that could mess up the system like calling malloc() or free().
  104. */
  105. static int playCallback( const void *inputBuffer, void *outputBuffer,
  106. unsigned long framesPerBuffer,
  107. const PaStreamCallbackTimeInfo* timeInfo,
  108. PaStreamCallbackFlags statusFlags,
  109. void *userData )
  110. {
  111. paTestData *data = (paTestData*)userData;
  112. SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
  113. SAMPLE *wptr = (SAMPLE*)outputBuffer;
  114. unsigned int i;
  115. int finished;
  116. unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
  117.  
  118. (void) inputBuffer; /* Prevent unused variable warnings. */
  119. (void) timeInfo;
  120. (void) statusFlags;
  121. (void) userData;
  122.  
  123. if( framesLeft < framesPerBuffer )
  124. {
  125. /* final buffer... */
  126. for( i=0; i<framesLeft; i++ )
  127. {
  128. *wptr++ = *rptr++; /* left */
  129. if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
  130. }
  131. for( ; i<framesPerBuffer; i++ )
  132. {
  133. *wptr++ = 0; /* left */
  134. if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */
  135. }
  136. data->frameIndex += framesLeft;
  137. finished = paComplete;
  138. }
  139. else
  140. {
  141. for( i=0; i<framesPerBuffer; i++ )
  142. {
  143. *wptr++ = *rptr++; /* left */
  144. if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
  145. }
  146. data->frameIndex += framesPerBuffer;
  147. finished = paContinue;
  148. }
  149. return finished;
  150. }
  151.  
  152. /*******************************************************************/
  153. int main(void);
  154. int main(void)
  155. {
  156. PaStreamParameters inputParameters,
  157. outputParameters;
  158. PaStream* stream;
  159. PaError err = paNoError;
  160. paTestData data;
  161. int i;
  162. int totalFrames;
  163. int numSamples;
  164. int numBytes;
  165. SAMPLE max, val;
  166. double average;
  167.  
  168. printf("patest_record.c\n"); fflush(stdout);
  169.  
  170. data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
  171. data.frameIndex = 0;
  172. numSamples = totalFrames * NUM_CHANNELS;
  173. numBytes = numSamples * sizeof(SAMPLE);
  174. data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
  175. if( data.recordedSamples == NULL )
  176. {
  177. printf("Could not allocate record array.\n");
  178. goto done;
  179. }
  180. for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
  181.  
  182. err = Pa_Initialize();
  183. if( err != paNoError ) goto done;
  184.  
  185. inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
  186. if (inputParameters.device == paNoDevice) {
  187. fprintf(stderr,"Error: No default input device.\n");
  188. goto done;
  189. }
  190. inputParameters.channelCount = 2; /* stereo input */
  191. inputParameters.sampleFormat = PA_SAMPLE_TYPE;
  192. inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
  193. inputParameters.hostApiSpecificStreamInfo = NULL;
  194.  
  195. /* Record some audio. -------------------------------------------- */
  196. err = Pa_OpenStream(
  197. &stream,
  198. &inputParameters,
  199. NULL, /* &outputParameters, */
  200. SAMPLE_RATE,
  201. FRAMES_PER_BUFFER,
  202. paClipOff, /* we won't output out of range samples so don't bother clipping them */
  203. recordCallback,
  204. &data );
  205. if( err != paNoError ) goto done;
  206.  
  207. err = Pa_StartStream( stream );
  208. if( err != paNoError ) goto done;
  209. printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout);
  210.  
  211. while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
  212. {
  213. Pa_Sleep(1000);
  214. printf("index = %d\n", data.frameIndex ); fflush(stdout);
  215. }
  216. if( err < 0 ) goto done;
  217.  
  218. err = Pa_CloseStream( stream );
  219. if( err != paNoError ) goto done;
  220.  
  221. /* Measure maximum peak amplitude. */
  222. max = 0;
  223. average = 0.0;
  224. for( i=0; i<numSamples; i++ )
  225. {
  226. val = data.recordedSamples[i];
  227. if( val < 0 ) val = -val; /* ABS */
  228. if( val > max )
  229. {
  230. max = val;
  231. }
  232. average += val;
  233. }
  234.  
  235. average = average / (double)numSamples;
  236.  
  237. printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
  238. printf("sample average = %lf\n", average );
  239.  
  240. /* Write recorded data to a file. */
  241. #if WRITE_TO_FILE
  242. {
  243. FILE *fid;
  244. fid = fopen("recorded.raw", "wb");
  245. if( fid == NULL )
  246. {
  247. printf("Could not open file.");
  248. }
  249. else
  250. {
  251. fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
  252. fclose( fid );
  253. printf("Wrote data to 'recorded.raw'\n");
  254. }
  255. }
  256. #endif
  257.  
  258. /* Playback recorded data. -------------------------------------------- */
  259. data.frameIndex = 0;
  260.  
  261. outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
  262. if (outputParameters.device == paNoDevice) {
  263. fprintf(stderr,"Error: No default output device.\n");
  264. goto done;
  265. }
  266. outputParameters.channelCount = 2; /* stereo output */
  267. outputParameters.sampleFormat = PA_SAMPLE_TYPE;
  268. outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
  269. outputParameters.hostApiSpecificStreamInfo = NULL;
  270.  
  271. printf("\n=== Now playing back. ===\n"); fflush(stdout);
  272. err = Pa_OpenStream(
  273. &stream,
  274. NULL, /* no input */
  275. &outputParameters,
  276. SAMPLE_RATE,
  277. FRAMES_PER_BUFFER,
  278. paClipOff, /* we won't output out of range samples so don't bother clipping them */
  279. playCallback,
  280. &data );
  281. if( err != paNoError ) goto done;
  282.  
  283. if( stream )
  284. {
  285. err = Pa_StartStream( stream );
  286. if( err != paNoError ) goto done;
  287.  
  288. printf("Waiting for playback to finish.\n"); fflush(stdout);
  289.  
  290. while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
  291. if( err < 0 ) goto done;
  292.  
  293. err = Pa_CloseStream( stream );
  294. if( err != paNoError ) goto done;
  295.  
  296. printf("Done.\n"); fflush(stdout);
  297. }
  298.  
  299. done:
  300. Pa_Terminate();
  301. if( data.recordedSamples ) /* Sure it is NULL or valid. */
  302. free( data.recordedSamples );
  303. if( err != paNoError )
  304. {
  305. fprintf( stderr, "An error occured while using the portaudio stream\n" );
  306. fprintf( stderr, "Error number: %d\n", err );
  307. fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
  308. err = 1; /* Always return 0 or 1, but no other return codes. */
  309. }
  310. return err;
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement