14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  AudioHardwareRecord.c  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h>
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h>
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <limits.h>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <unistd.h>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <sys/select.h>
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "audioinwrapper.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SAMPLING_RATE        8000
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_FRAMES_PER_BUFFER   512  /* low-level driver counts in terms of frames, not samples */
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_TUPLES_PER_FRAME      1  /* tuple: a set of samples (set of 1 if mono, set of 2 if stereo */
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_CHANNELS_PER_TUPLE    1  /* 1: mono; 2: stereo */
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_TUPLES_PER_BUFFER   (N_FRAMES_PER_BUFFER * N_TUPLES_PER_FRAME)
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_SAMPLES_PER_BUFFER  (N_TUPLES_PER_BUFFER * N_CHANNELS_PER_TUPLE)
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_RECORDINGS         1000
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_SECONDS_TO_RECORD    5
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define N_SAMPLES_TO_RECORD   (SAMPLING_RATE * N_SECONDS_TO_RECORD * N_CHANNELS_PER_TUPLE)
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttypedef short typeSample;
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* store incoming samples here, then write to file at the end */
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjecttypeSample recordedSamples[N_SAMPLES_TO_RECORD];
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//#define AUDIO_SET_FORMAT_ONCE_ONLY
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint main(int argc, char* argv[])
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int           rc;
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    unsigned int  iFile;
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const unsigned short delay_ms = 2000; //1800 //340;
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    printf("For debugging, this is configured to sleep for %u milliseconds before AudioSetInputFormat(%u)\n\n", delay_ms, SAMPLING_RATE);
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if defined(AUDIO_SET_FORMAT_ONCE_ONLY)
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = AudioSetInputFormat(SAMPLING_RATE, N_CHANNELS_PER_TUPLE);
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rc != 0)
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("ERROR: AudioSetInputFormat() returns %d\n", rc);
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        exit(1);
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (iFile = 1; iFile <= N_RECORDINGS; iFile++)
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        unsigned int  i;
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if !defined(AUDIO_SET_FORMAT_ONCE_ONLY)
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          	// see how much of a delay is needed to get rid of error when calling
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          	// AudioSetInputFormat() immediately after AudioClose()
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          	struct timeval  sleep_time_struct;
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          	sleep_time_struct.tv_sec = 0;
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          	sleep_time_struct.tv_usec = delay_ms*1000; // microseconds
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     				select(0, NULL, NULL, NULL, &sleep_time_struct);
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = AudioSetInputFormat(SAMPLING_RATE, N_CHANNELS_PER_TUPLE);
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rc != 0)
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("ERROR: AudioSetInputFormat() returns %d\n", rc);
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            exit(1);
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        printf("Recording: %3d of %3d\n", iFile, N_RECORDINGS);
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        memset(recordedSamples, 0, N_SAMPLES_TO_RECORD * sizeof(typeSample));
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = AudioOpen();
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rc < 0)
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("ERROR: AudioOpen() returns %d (device handle/ID)\n", rc);
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            exit(1);
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        i = 0;
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        while (i <= N_SAMPLES_TO_RECORD - N_SAMPLES_PER_BUFFER)
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            rc = AudioRead(&(recordedSamples[i]), N_FRAMES_PER_BUFFER);
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (rc > 0)
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                i += (rc * N_TUPLES_PER_FRAME * N_CHANNELS_PER_TUPLE);
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            else
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                printf("ERROR: AudioRead() returns %d\n", rc);
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        rc = AudioClose();
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (rc != 0)
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("ERROR: AudioClose() returns %d\n", rc);
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            exit(1);
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* write to file  */
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if 0
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            FILE *fpOutput;
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            char szFilename[256];
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            sprintf(szFilename, "output_AudioHardwareRecordLoop_%03d.pcm", iFile);
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fpOutput = fopen(szFilename, "wb");
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (fpOutput == NULL)
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                printf("ERROR: cannot create '%s'\n", szFilename);
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                exit(1);
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fwrite(recordedSamples, sizeof(typeSample), i, fpOutput);
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            fclose(fpOutput);
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            printf("Recording: saved '%s'\n", szFilename);
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
141