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
42typedef short typeSample;
43
44/* store incoming samples here, then write to file at the end */
45typeSample recordedSamples[N_SAMPLES_TO_RECORD];
46
47//#define AUDIO_SET_FORMAT_ONCE_ONLY
48
49int 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