/*---------------------------------------------------------------------------*
* audioinwrapper.cpp *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#if defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
//#define USE_DEV_EAC_FILE 1
#if defined(USE_DEV_EAC_FILE)
#include <fcntl.h>
#define N_CHANNELS 1
#else
#include <system/audio.h>
#include <media/AudioRecord.h>
#include <media/mediarecorder.h>
using namespace android;
#endif
#endif // defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
#include "plog.h"
// #define SAVE_RAW_AUDIO 1
#ifdef SAVE_RAW_AUDIO
#include <sys/time.h>
#include <stdio.h>
static FILE *audio_data;
static struct timeval buffer_save_audio;
#endif
extern "C"
{
#if defined(ANDROID) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_4__))
#if defined(USE_DEV_EAC_FILE)
static int audiofd = -1;
#else
static AudioRecord* record;
static int sampleRate = 8000;
static int numChannels = 1;
#endif
// called before AudioOpen
int AudioSetInputFormat(int sample_rate, int channel_count)
{
#if defined(USE_DEV_EAC_FILE)
return 0;
#else
sampleRate = sample_rate;
numChannels = channel_count;
return 0;
#endif
}
int AudioOpen(void)
{
#if defined(USE_DEV_EAC_FILE)
audiofd = open("/dev/eac", O_RDONLY, 0666);
if (audiofd >= 0) {
//fcntl(audiofd, F_SETFL, O_NONBLOCK);
// possibly lame attempt to get Sooner audio input working
struct { unsigned long param1, param2, param3; } params = { 11025, 0, 0 };
ioctl(audiofd, 317, ¶ms, sizeof(params));
}
return audiofd;
#else
#ifdef SAVE_RAW_AUDIO
char file_name [256];
gettimeofday ( &buffer_save_audio, NULL );
sprintf ( file_name, "data_%ld_%ld.raw", buffer_save_audio.tv_sec, buffer_save_audio.tv_usec );
audio_data = fopen ( file_name, "w" );
#endif
// TODO: get record buffer size from hardware.
record = new android::AudioRecord(
AUDIO_SOURCE_DEFAULT,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
(numChannels > 1) ? AUDIO_CHANNEL_IN_STEREO : AUDIO_CHANNEL_IN_MONO,
8*1024);
if (!record) return -1;
return record->start() == NO_ERROR ? 0 : -1;
#endif
}
int AudioClose(void)
{
#if defined(USE_DEV_EAC_FILE)
return close(audiofd);
#else
record->stop();
delete record;
#ifdef SAVE_RAW_AUDIO
fclose ( audio_data );
#endif
return 0;
#endif
}
int AudioRead(short *buffer, int frame_count)
{
int n;
#if defined(USE_DEV_EAC_FILE)
n = read(audiofd, buffer, frame_count*sizeof(short)*N_CHANNELS);
n /= sizeof(short)*N_CHANNELS;
return n;
#else
int nreq = frame_count * sizeof(short);
n = record->read(buffer, nreq);
if (n > 0) {
if (n != nreq) {
PLogError ( "AudioRead error: not enough data %d vs %d\n", n, nreq );
}
n /= sizeof(short);
}
#ifdef SAVE_RAW_AUDIO
if ( n > 0 )
fwrite ( buffer, 2, n, audio_data );
#endif
return n;
#endif
}
int AudioSetVolume(int stream_type, int volume)
{
#if defined(USE_DEV_EAC_FILE)
return 0;
#else
return AudioSystem::setStreamVolume(stream_type, volume, 0);
#endif
}
int AudioGetVolume(int stream_type)
{
#if defined(USE_DEV_EAC_FILE)
return 0;
#else
float v = 0;
AudioSystem::getStreamVolume(stream_type, &v, 0);
return int(v * 100.0f);
#endif
}
#else
int AudioOpen(void)
{
return -1;
}
int AudioClose(void)
{
return -1;
}
int AudioSetInputFormat(int sample_rate, int channel_count)
{
return -1;
}
int AudioSetOutputFormat(int sample_rate, int channel_count)
{
return -1;
}
int AudioRead(short *buffer, int frame_count)
{
return -1;
}
int AudioWrite(short *buffer, int frame_count)
{
return -1;
}
int AudioSetStreamType(int stream_type)
{
return -1;
}
int AudioSetVolume(int stream_type, int volume)
{
return -1;
}
int AudioGetVolume(int stream_type)
{
return -1;
}
#endif
} // extern "C"