1 /*---------------------------------------------------------------------------* 2 * AudioHardwareRecord.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <limits.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <sys/select.h> 26 #include "audioinwrapper.h" 27 28 #define SAMPLING_RATE 8000 29 30 #define N_FRAMES_PER_BUFFER 512 /* low-level driver counts in terms of frames, not samples */ 31 #define N_TUPLES_PER_FRAME 1 /* tuple: a set of samples (set of 1 if mono, set of 2 if stereo */ 32 33 #define N_CHANNELS_PER_TUPLE 1 /* 1: mono; 2: stereo */ 34 35 #define N_TUPLES_PER_BUFFER (N_FRAMES_PER_BUFFER * N_TUPLES_PER_FRAME) 36 #define N_SAMPLES_PER_BUFFER (N_TUPLES_PER_BUFFER * N_CHANNELS_PER_TUPLE) 37 38 #define N_RECORDINGS 1000 39 #define N_SECONDS_TO_RECORD 5 40 #define N_SAMPLES_TO_RECORD (SAMPLING_RATE * N_SECONDS_TO_RECORD * N_CHANNELS_PER_TUPLE) 41 42 typedef short typeSample; 43 44 /* store incoming samples here, then write to file at the end */ 45 typeSample recordedSamples[N_SAMPLES_TO_RECORD]; 46 47 //#define AUDIO_SET_FORMAT_ONCE_ONLY 48 49 int main(int argc, char* argv[]) 50 { 51 int rc; 52 unsigned int iFile; 53 54 const unsigned short delay_ms = 2000; //1800 //340; 55 56 printf("For debugging, this is configured to sleep for %u milliseconds before AudioSetInputFormat(%u)\n\n", delay_ms, SAMPLING_RATE); 57 58 #if defined(AUDIO_SET_FORMAT_ONCE_ONLY) 59 rc = AudioSetInputFormat(SAMPLING_RATE, N_CHANNELS_PER_TUPLE); 60 if (rc != 0) 61 { 62 printf("ERROR: AudioSetInputFormat() returns %d\n", rc); 63 exit(1); 64 } 65 #endif 66 67 for (iFile = 1; iFile <= N_RECORDINGS; iFile++) 68 { 69 unsigned int i; 70 71 #if !defined(AUDIO_SET_FORMAT_ONCE_ONLY) 72 { 73 // see how much of a delay is needed to get rid of error when calling 74 // AudioSetInputFormat() immediately after AudioClose() 75 struct timeval sleep_time_struct; 76 sleep_time_struct.tv_sec = 0; 77 sleep_time_struct.tv_usec = delay_ms*1000; // microseconds 78 select(0, NULL, NULL, NULL, &sleep_time_struct); 79 } 80 81 rc = AudioSetInputFormat(SAMPLING_RATE, N_CHANNELS_PER_TUPLE); 82 if (rc != 0) 83 { 84 printf("ERROR: AudioSetInputFormat() returns %d\n", rc); 85 exit(1); 86 } 87 #endif 88 89 printf("Recording: %3d of %3d\n", iFile, N_RECORDINGS); 90 91 memset(recordedSamples, 0, N_SAMPLES_TO_RECORD * sizeof(typeSample)); 92 93 rc = AudioOpen(); 94 if (rc < 0) 95 { 96 printf("ERROR: AudioOpen() returns %d (device handle/ID)\n", rc); 97 exit(1); 98 } 99 100 i = 0; 101 while (i <= N_SAMPLES_TO_RECORD - N_SAMPLES_PER_BUFFER) 102 { 103 rc = AudioRead(&(recordedSamples[i]), N_FRAMES_PER_BUFFER); 104 if (rc > 0) 105 i += (rc * N_TUPLES_PER_FRAME * N_CHANNELS_PER_TUPLE); 106 else 107 printf("ERROR: AudioRead() returns %d\n", rc); 108 } 109 110 rc = AudioClose(); 111 if (rc != 0) 112 { 113 printf("ERROR: AudioClose() returns %d\n", rc); 114 exit(1); 115 } 116 117 /* write to file */ 118 #if 0 119 { 120 FILE *fpOutput; 121 char szFilename[256]; 122 123 sprintf(szFilename, "output_AudioHardwareRecordLoop_%03d.pcm", iFile); 124 125 fpOutput = fopen(szFilename, "wb"); 126 if (fpOutput == NULL) 127 { 128 printf("ERROR: cannot create '%s'\n", szFilename); 129 exit(1); 130 } 131 fwrite(recordedSamples, sizeof(typeSample), i, fpOutput); 132 fclose(fpOutput); 133 134 printf("Recording: saved '%s'\n", szFilename); 135 } 136 #endif 137 } 138 139 return 0; 140 } 141