1/*---------------------------------------------------------------------------*
2 *  audioinwrapper.cpp                                                       *
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
21#if defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
22
23//#define USE_DEV_EAC_FILE 1
24
25#if defined(USE_DEV_EAC_FILE)
26#include <fcntl.h>
27#define N_CHANNELS 1
28#else
29#include <system/audio.h>
30#include <media/AudioRecord.h>
31#include <media/mediarecorder.h>
32using namespace android;
33#endif
34
35#endif // defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
36
37#include "plog.h"
38
39// #define SAVE_RAW_AUDIO              1
40
41#ifdef SAVE_RAW_AUDIO
42#include <sys/time.h>
43#include <stdio.h>
44
45
46static FILE *audio_data;
47static struct timeval buffer_save_audio;
48#endif
49
50
51extern "C"
52{
53
54#if defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
55
56#if defined(USE_DEV_EAC_FILE)
57static int audiofd = -1;
58#else
59static AudioRecord* record;
60static int sampleRate = 8000;
61static int numChannels = 1;
62#endif
63
64// called before AudioOpen
65int AudioSetInputFormat(int sample_rate, int channel_count)
66{
67#if defined(USE_DEV_EAC_FILE)
68  return 0;
69#else
70  sampleRate = sample_rate;
71  numChannels = channel_count;
72  return 0;
73#endif
74}
75
76int AudioOpen(void)
77{
78#if defined(USE_DEV_EAC_FILE)
79  audiofd = open("/dev/eac", O_RDONLY, 0666);
80  if (audiofd >= 0) {
81    //fcntl(audiofd, F_SETFL, O_NONBLOCK);
82
83    // possibly lame attempt to get Sooner audio input working
84    struct { unsigned long param1, param2, param3; } params = { 11025, 0, 0 };
85    ioctl(audiofd, 317, &params, sizeof(params));
86  }
87
88  return audiofd;
89#else
90    #ifdef SAVE_RAW_AUDIO
91        char file_name [256];
92
93        gettimeofday ( &buffer_save_audio, NULL );
94        sprintf ( file_name, "data_%ld_%ld.raw", buffer_save_audio.tv_sec, buffer_save_audio.tv_usec );
95        audio_data = fopen ( file_name, "w" );
96    #endif
97// TODO: get record buffer size from hardware.
98    record = new android::AudioRecord(
99                            AUDIO_SOURCE_DEFAULT,
100                            sampleRate,
101                            AUDIO_FORMAT_PCM_16_BIT,
102                            (numChannels > 1) ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_IN_MONO,
103                            8*1024,
104                            0);
105
106  if (!record) return -1;
107
108  return record->start() == NO_ERROR ? 0 : -1;
109#endif
110}
111
112int AudioClose(void)
113{
114#if defined(USE_DEV_EAC_FILE)
115  return close(audiofd);
116#else
117  record->stop();
118  delete record;
119    #ifdef SAVE_RAW_AUDIO
120        fclose ( audio_data );
121    #endif
122  return 0;
123#endif
124}
125
126int AudioRead(short *buffer, int frame_count)
127{
128  int n;
129#if defined(USE_DEV_EAC_FILE)
130  n = read(audiofd, buffer, frame_count*sizeof(short)*N_CHANNELS);
131  n /= sizeof(short)*N_CHANNELS;
132  return n;
133#else
134  int nreq = frame_count * sizeof(short);
135  n = record->read(buffer, nreq);
136  if (n > 0) {
137    if (n != nreq) {
138      PLogError ( "AudioRead error: not enough data %d vs %d\n", n, nreq );
139    }
140    n /= sizeof(short);
141  }
142    #ifdef SAVE_RAW_AUDIO
143        if ( n > 0 )
144            fwrite ( buffer, 2, n, audio_data );
145    #endif
146  return n;
147#endif
148}
149
150int AudioSetVolume(int stream_type, int volume)
151{
152#if defined(USE_DEV_EAC_FILE)
153  return 0;
154#else
155  return AudioSystem::setStreamVolume(stream_type, volume, 0);
156#endif
157}
158
159int AudioGetVolume(int stream_type)
160{
161#if defined(USE_DEV_EAC_FILE)
162  return 0;
163#else
164  float v = 0;
165  AudioSystem::getStreamVolume(stream_type, &v, 0);
166  return int(v * 100.0f);
167#endif
168}
169
170#else
171
172int AudioOpen(void)
173{
174  return -1;
175}
176
177int AudioClose(void)
178{
179  return -1;
180}
181
182int AudioSetInputFormat(int sample_rate, int channel_count)
183{
184  return -1;
185}
186
187int AudioSetOutputFormat(int sample_rate, int channel_count)
188{
189  return -1;
190}
191
192int AudioRead(short *buffer, int frame_count)
193{
194  return -1;
195}
196
197int AudioWrite(short *buffer, int frame_count)
198{
199  return -1;
200}
201
202int AudioSetStreamType(int stream_type)
203{
204  return -1;
205}
206
207int AudioSetVolume(int stream_type, int volume)
208{
209  return -1;
210}
211
212int AudioGetVolume(int stream_type)
213{
214  return -1;
215}
216
217#endif
218
219} // extern "C"
220