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
105  if (!record) return -1;
106
107  return record->start() == NO_ERROR ? 0 : -1;
108#endif
109}
110
111int AudioClose(void)
112{
113#if defined(USE_DEV_EAC_FILE)
114  return close(audiofd);
115#else
116  record->stop();
117  delete record;
118    #ifdef SAVE_RAW_AUDIO
119        fclose ( audio_data );
120    #endif
121  return 0;
122#endif
123}
124
125int AudioRead(short *buffer, int frame_count)
126{
127  int n;
128#if defined(USE_DEV_EAC_FILE)
129  n = read(audiofd, buffer, frame_count*sizeof(short)*N_CHANNELS);
130  n /= sizeof(short)*N_CHANNELS;
131  return n;
132#else
133  int nreq = frame_count * sizeof(short);
134  n = record->read(buffer, nreq);
135  if (n > 0) {
136    if (n != nreq) {
137      PLogError ( "AudioRead error: not enough data %d vs %d\n", n, nreq );
138    }
139    n /= sizeof(short);
140  }
141    #ifdef SAVE_RAW_AUDIO
142        if ( n > 0 )
143            fwrite ( buffer, 2, n, audio_data );
144    #endif
145  return n;
146#endif
147}
148
149int AudioSetVolume(int stream_type, int volume)
150{
151#if defined(USE_DEV_EAC_FILE)
152  return 0;
153#else
154  return AudioSystem::setStreamVolume(stream_type, volume, 0);
155#endif
156}
157
158int AudioGetVolume(int stream_type)
159{
160#if defined(USE_DEV_EAC_FILE)
161  return 0;
162#else
163  float v = 0;
164  AudioSystem::getStreamVolume(stream_type, &v, 0);
165  return int(v * 100.0f);
166#endif
167}
168
169#else
170
171int AudioOpen(void)
172{
173  return -1;
174}
175
176int AudioClose(void)
177{
178  return -1;
179}
180
181int AudioSetInputFormat(int sample_rate, int channel_count)
182{
183  return -1;
184}
185
186int AudioSetOutputFormat(int sample_rate, int channel_count)
187{
188  return -1;
189}
190
191int AudioRead(short *buffer, int frame_count)
192{
193  return -1;
194}
195
196int AudioWrite(short *buffer, int frame_count)
197{
198  return -1;
199}
200
201int AudioSetStreamType(int stream_type)
202{
203  return -1;
204}
205
206int AudioSetVolume(int stream_type, int volume)
207{
208  return -1;
209}
210
211int AudioGetVolume(int stream_type)
212{
213  return -1;
214}
215
216#endif
217
218} // extern "C"
219