summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libaudio/AudioHardwareALSA.cpp663
-rwxr-xr-xlibaudio/AudioHardwareALSA.h73
2 files changed, 423 insertions, 313 deletions
diff --git a/libaudio/AudioHardwareALSA.cpp b/libaudio/AudioHardwareALSA.cpp
index 88598b7..52d0418 100644
--- a/libaudio/AudioHardwareALSA.cpp
+++ b/libaudio/AudioHardwareALSA.cpp
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <unistd.h>
+//#define LOG_NDEBUG 0
#define LOG_TAG "AudioHardwareALSA"
#include <utils/Log.h>
#include <utils/String8.h>
@@ -40,9 +41,6 @@
// sangsu fix : headers for IPC
#include <telephony/ril.h>
#endif
-#ifndef ALSA_DEFAULT_SAMPLE_RATE
-#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
-#endif
#define SND_MIXER_VOL_RANGE_MIN (0)
#define SND_MIXER_VOL_RANGE_MAX (100)
@@ -53,10 +51,6 @@
if (strlen(x) + strlen(y) < ALSA_NAME_MAX) \
strcat(x, y);
-#define PERIOD_PLAYBACK 4
-#define PERIOD_CAPTURE 4
-#define PLAYBACK 0
-#define CAPTURE 1
// If you want to dump PCM data, activate this feature
//#define PCM_INPUT_DUMP
@@ -128,7 +122,6 @@ typedef AudioSystem::audio_devices audio_routes;
#endif
// ----------------------------------------------------------------------------
-static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
static const char _nullALSADeviceName[] = "NULL_Device";
@@ -163,7 +156,7 @@ static const char *deviceSuffix[] = {
/* ROUTE_HEADSET */ "_Headset",
/* ROUTE_HEADPHONE */ "_Headset",
/* ROUTE_BLUETOOTH_SCO */ "_Bluetooth",
- /* ROUTE_BLUETOOTH_SCO_HEADSET */ "_Bluetooth",
+ /* ROUTE_BLUETOOTH_SCO_HEADSET */ "_Bluetooth",
/* ROUTE_BLUETOOTH_SCO_CARKIT */ "_Bluetooth", //"_Bluetooth_Carkit"
/* ROUTE_BLUETOOTH_A2DP */ "_Bluetooth", //"_Bluetooth-A2DP"
/* ROUTE_BLUETOOTH_A2DP_HEADPHONES */ "_Bluetooth", //"_Bluetooth-A2DP_HeadPhone"
@@ -174,7 +167,7 @@ static const char *deviceSuffix[] = {
/* ROUTE_NULL */ "_Null",
/* ROUTE_NULL */ "_Null",
/* ROUTE_DEFAULT */ "_OutDefault",
-
+
// input devices
/* ROUTE_COMMUNICATION */ "_Communication",
/* ROUTE_AMBIENT */ "_Ambient",
@@ -250,6 +243,10 @@ mixerProp[][SND_PCM_STREAM_LAST+1] = {
}
};
+const uint32_t AudioHardwareALSA::inputSamplingRates[] = {
+ 44100, 22050, 11025
+};
+
// ----------------------------------------------------------------------------
AudioHardwareALSA::AudioHardwareALSA() :
@@ -261,7 +258,7 @@ AudioHardwareALSA::AudioHardwareALSA() :
#if defined TURN_ON_DEVICE_ONLY_USE
,mActivatedInputDevice(false)
#endif
-#if defined SYNCHRONIZE_CP
+#if defined SYNCHRONIZE_CP
,mActivatedCP(false)
#endif
@@ -315,12 +312,12 @@ status_t AudioHardwareALSA::setVoiceVolume(float volume)
LOGI("### earpiece call volume");
mIPC->transmitVolumeIPC(OEM_SOUND_TYPE_VOICE, volume);
break;
-
- case AudioSystem::ROUTE_SPEAKER:
+
+ case AudioSystem::ROUTE_SPEAKER:
LOGI("### speaker call volume");
mIPC->transmitVolumeIPC(OEM_SOUND_TYPE_SPEAKER, volume);
break;
-
+
case AudioSystem::ROUTE_BLUETOOTH_SCO:
case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
case AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
@@ -328,15 +325,15 @@ status_t AudioHardwareALSA::setVoiceVolume(float volume)
LOGI("### bluetooth call volume");
mIPC->transmitVolumeIPC(OEM_SOUND_TYPE_BTVOICE, volume);
break;
-
+
case AudioSystem::ROUTE_HEADSET:
LOGI("### headset call volume");
mIPC->transmitVolumeIPC(OEM_SOUND_TYPE_HEADSET, volume);
break;
-
+
default:
LOGE("### Call volume setting error!!!0x%08x \n", routes);
- break;
+ break;
}
}
// sangsu fix end
@@ -405,7 +402,7 @@ AudioHardwareALSA::openOutputStream(
{
fpOutput = fopen(PCM_OUTPUT_DUMP_PATH, "w");
if (fpOutput == NULL)
- LOGE("fpOutput File Open Error!!");
+ LOGE("fpOutput File Open Error!!");
}
#endif
@@ -418,6 +415,7 @@ AudioHardwareALSA::openOutputStream(
//mOutput->setDevice(mMode, routes);
LOGI("%s] Setting ALSA device.", __func__);
mOutput->setDevice(mMode, devices, PLAYBACK); /* tushar - Enable all devices as of now */
+ mOutput->setWakeLock();
}
else {
delete out;
@@ -426,7 +424,7 @@ AudioHardwareALSA::openOutputStream(
return mOutput;
}
-void
+void
AudioHardwareALSA::closeOutputStream(AudioStreamOut* out)
{
/* TODO:Tushar: May lead to segmentation fault - check*/
@@ -456,7 +454,7 @@ AudioHardwareALSA::openInputStream(int format,
status_t *status,
AudioSystem::audio_in_acoustics acoustics)
#else
-AudioStreamIn*
+AudioStreamIn*
AudioHardwareALSA::openInputStream(
uint32_t devices,
int *format,
@@ -482,23 +480,23 @@ AudioHardwareALSA::openInputStream(
// Some information is expected to be available immediately after
// the device is open.
//uint32_t routes = mRoutes[mMode];
- //mInput->setDevice(mMode, routes);
+ //mInput->setDevice(mMode, routes);
mInput->setDevice(mMode, devices, CAPTURE); /* Tushar - as per modified arch */
+ mInput->setWakeLock();
#if defined TURN_ON_DEVICE_ONLY_USE
mActivatedInputDevice = true;
setMicStatus(1);
-
+#endif
#ifdef PCM_INPUT_DUMP
- if(fpInput == NULL)
- {
- fpInput = fopen(PCM_INPUT_DUMP_PATH, "w");
- if (fpInput == NULL)
- LOGE("fpInput File Open Error!!");
- }
+ if(fpInput == NULL)
+ {
+ fpInput = fopen(PCM_INPUT_DUMP_PATH, "w");
+ if (fpInput == NULL)
+ LOGE("fpInput File Open Error!!");
+ }
#endif
-#endif
- return mInput;
+ return mInput;
}
else {
delete in;
@@ -547,9 +545,9 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
// Setup sound path for CP clocking
#if defined SEC_IPC
-
+
if (AudioSystem::MODE_IN_CALL == mode)
- {
+ {
LOGI("### incall mode route (%d)", routes);
switch(routes){
@@ -557,12 +555,12 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
LOGI("### incall mode earpiece route");
mIPC->transmitAudioPathIPC(OEM_SOUND_AUDIO_PATH_HANDSET);
break;
-
+
case AudioSystem::ROUTE_SPEAKER:
LOGI("### incall mode speaker route");
mIPC->transmitAudioPathIPC(OEM_SOUND_AUDIO_PATH_SPEAKER);
break;
-
+
case AudioSystem::ROUTE_BLUETOOTH_SCO:
case AudioSystem::ROUTE_BLUETOOTH_SCO_HEADSET:
case AudioSystem::ROUTE_BLUETOOTH_SCO_CARKIT:
@@ -570,7 +568,7 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
if(mBluetoothECOff)
{
LOGI("### incall mode bluetooth EC OFF route");
- mIPC->transmitAudioPathIPC(OEM_SOUND_AUDIO_PATH_BT_NSEC_OFF);
+ mIPC->transmitAudioPathIPC(OEM_SOUND_AUDIO_PATH_BT_NSEC_OFF);
}
else
{
@@ -604,8 +602,8 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
#if defined SEC_IPC
if (AudioSystem::MODE_IN_CALL == mode)
- {
-#if defined SYNCHRONIZE_CP
+ {
+#if defined SYNCHRONIZE_CP
if(!mActivatedCP)
{
mIPC->transmitClock_IPC(OEM_SOUND_CLOCK_START);
@@ -616,7 +614,7 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
if (AudioSystem::MODE_NORMAL== mode) // Call stop.
{
-#if defined SYNCHRONIZE_CP
+#if defined SYNCHRONIZE_CP
if(mActivatedCP)
mActivatedCP = false;
#endif
@@ -624,8 +622,8 @@ status_t AudioHardwareALSA::doRouting(uint32_t device)
}
#endif // end of #if defined SEC_IPC
-#ifndef SYNCHRONIZE_CP
- ret = mOutput->setDevice(mode, routes, PLAYBACK);
+#ifndef SYNCHRONIZE_CP
+// ret = mOutput->setDevice(mode, routes, PLAYBACK);
#endif
return ret;
}
@@ -675,8 +673,7 @@ status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args)
size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
- if (sampleRate != 8000 && sampleRate != 11025 && sampleRate != 16000 && sampleRate != 22050 &&
- sampleRate != 24000 && sampleRate != 32000 && sampleRate != 44100 && sampleRate != 48000) {
+ if (sampleRate < 8000 || sampleRate > 48000) {
LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
return 0;
}
@@ -689,14 +686,33 @@ size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, in
return 0;
}
-#if defined SEC_SWP_SOUND
- if (sampleRate == 32000 || sampleRate == 44100 || sampleRate == 48000)
- return READ_FRAME_SIZE_STANDARD;
- else
- return READ_FRAME_SIZE;
-#else /* SEC_SWP_SOUND */
- return 320;
-#endif /* SEC_SWP_SOUND */
+ uint32_t shift = checkInputSampleRate(sampleRate);
+ size_t size = (PERIOD_SZ_CAPTURE >> shift) * sizeof(int16_t);
+ LOGV("getInputBufferSize() rate %d, shift %d, size %d", sampleRate, shift, size);
+ return size;
+
+//#if defined SEC_SWP_SOUND
+// if (sampleRate == 32000 || sampleRate == 44100 || sampleRate == 48000)
+// return READ_FRAME_SIZE_STANDARD;
+// else
+// return READ_FRAME_SIZE;
+//#else /* SEC_SWP_SOUND */
+// return 320;
+//#endif /* SEC_SWP_SOUND */
+}
+
+uint32_t AudioHardwareALSA::checkInputSampleRate(uint32_t sampleRate)
+{
+ uint32_t i;
+ uint32_t prevDelta;
+ uint32_t delta;
+
+ for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) {
+ delta = abs(sampleRate - inputSamplingRates[i]);
+ if (delta > prevDelta) break;
+ }
+ // i is always > 0 here
+ return i-1;
}
// ----------------------------------------------------------------------------
@@ -741,23 +757,35 @@ status_t ALSAStreamOps::set(int *pformat,
LOGD("ALSAStreamOps - input - format = %d, channels = %d, rate = %d\n", lformat, lchannels, lrate);
- LOGD("ALSAStreamOps - default - format = %d, channels = %d, rate = %d\n", mDefaults->format, mDefaults->channels, mDefaults->sampleRate);
+ LOGD("ALSAStreamOps - default - format = %d, channelCount = %d, rate = %d\n", mDefaults->format, mDefaults->channelCount, mDefaults->sampleRate);
if(lformat == 0) lformat = getAndroidFormat(mDefaults->format);//format();
- if(lchannels == 0) lchannels = getAndroidChannels(mDefaults->channels);// channelCount();
- if(lrate == 0) lrate = mDefaults->sampleRate;
+ if(lchannels == 0) lchannels = getAndroidChannels(mDefaults->channelCount);// channelCount();
+ if(lrate == 0) lrate = mDefaults->sampleRate;
if((lformat != getAndroidFormat(mDefaults->format)) ||
- (lchannels != getAndroidChannels(mDefaults->channels)) ||
- (lrate != mDefaults->sampleRate)){
+ (lchannels != getAndroidChannels(mDefaults->channelCount))) {
if(pformat) *pformat = getAndroidFormat(mDefaults->format);
- if(pchannels) *pchannels = getAndroidChannels(mDefaults->channels);
- if(prate) *prate = mDefaults->sampleRate;
+ if(pchannels) *pchannels = getAndroidChannels(mDefaults->channelCount);
return BAD_VALUE;
- }
+ }
+ if (mDefaults->direction == SND_PCM_STREAM_PLAYBACK) {
+ if (lrate != mDefaults->sampleRate) {
+ if(prate) *prate = mDefaults->sampleRate;
+ return BAD_VALUE;
+ }
+ } else {
+ mDefaults->smpRateShift = AudioHardwareALSA::checkInputSampleRate(lrate);
+ // audioFlinger will reopen the input stream with correct smp rate
+ if (AudioHardwareALSA::inputSamplingRates[mDefaults->smpRateShift] != lrate) {
+ if(prate) *prate = AudioHardwareALSA::inputSamplingRates[mDefaults->smpRateShift];
+ return BAD_VALUE;
+ }
+ }
+ mDefaults->sampleRate = lrate;
if(pformat) *pformat = getAndroidFormat(mDefaults->format);
- if(pchannels) *pchannels = getAndroidChannels(mDefaults->channels);
+ if(pchannels) *pchannels = getAndroidChannels(mDefaults->channelCount);
if(prate) *prate = mDefaults->sampleRate;
return NO_ERROR;
@@ -766,14 +794,16 @@ status_t ALSAStreamOps::set(int *pformat,
uint32_t ALSAStreamOps::sampleRate() const
{
- unsigned int rate;
- int err;
-
- if (! mHandle)
- return NO_INIT;
+// unsigned int rate;
+// int err;
+//
+// if (! mHandle)
+// return NO_INIT;
+//
+// return snd_pcm_hw_params_get_rate(mHardwareParams, &rate, 0) < 0
+// ? 0 : static_cast<uint32_t>(rate);
- return snd_pcm_hw_params_get_rate(mHardwareParams, &rate, 0) < 0
- ? 0 : static_cast<uint32_t>(rate);
+ return mDefaults->sampleRate;
}
status_t ALSAStreamOps::sampleRate(uint32_t rate)
@@ -817,18 +847,12 @@ size_t ALSAStreamOps::bufferSize() const
{
int err;
- if (!mHandle)
- return -1;
+ size_t size = ((mDefaults->periodSize >> mDefaults->smpRateShift) * mDefaults->channelCount *
+ snd_pcm_format_physical_width(mDefaults->format)) / 8;
+ LOGV("bufferSize() channelCount %d, shift %d, size %d",
+ mDefaults->channelCount, mDefaults->smpRateShift, size);
+ return size;
- snd_pcm_uframes_t bufferSize = 0;
- snd_pcm_uframes_t periodSize = 0;
-
- err = snd_pcm_get_params(mHandle, &bufferSize, &periodSize);
-
- if (err < 0)
- return -1;
-
- return static_cast<size_t>(snd_pcm_frames_to_bytes(mHandle, bufferSize));
}
int ALSAStreamOps::getAndroidFormat(snd_pcm_format_t format)
@@ -861,8 +885,8 @@ int ALSAStreamOps::format() const
int pcmFormatBitWidth;
int audioSystemFormat;
- if (!mHandle)
- return -1;
+// if (!mHandle)
+// return -1;
if (snd_pcm_hw_params_get_format(mHardwareParams, &ALSAFormat) < 0) {
return -1;
@@ -886,86 +910,70 @@ int ALSAStreamOps::format() const
return audioSystemFormat;
}
-uint32_t ALSAStreamOps::getAndroidChannels(int channels)
+uint32_t ALSAStreamOps::getAndroidChannels(int channelCount) const
{
int AudioSystemChannels = AudioSystem::DEFAULT;
- switch(channels){
- case 1:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_FRONT_RIGHT;
- break;
- case 2:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_STEREO;
- break;
- case 4:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_QUAD;
- break;
- case 6:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_5POINT1;
- break;
- defualt:
- LOGE("FATAL: AudioSystem does not support %d channels.", channels);
- }
+ if (mDefaults->direction == SND_PCM_STREAM_PLAYBACK) {
+ switch(channelCount){
+ case 1:
+ AudioSystemChannels = AudioSystem::CHANNEL_OUT_MONO;
+ break;
+ case 2:
+ AudioSystemChannels = AudioSystem::CHANNEL_OUT_STEREO;
+ break;
+ case 4:
+ AudioSystemChannels = AudioSystem::CHANNEL_OUT_QUAD;
+ break;
+ case 6:
+ AudioSystemChannels = AudioSystem::CHANNEL_OUT_5POINT1;
+ break;
+ default:
+ LOGE("FATAL: AudioSystem does not support %d output channels.", channelCount);
+ }
+ } else {
+ switch(channelCount){
+ case 1:
+ AudioSystemChannels = AudioSystem::CHANNEL_IN_MONO;
+ break;
+ case 2:
+ AudioSystemChannels = AudioSystem::CHANNEL_IN_STEREO;
+ break;
+ default:
+ LOGE("FATAL: AudioSystem does not support %d input channels.", channelCount);
+ }
+
+ }
return AudioSystemChannels;
}
-int ALSAStreamOps::channelCount() const
+uint32_t ALSAStreamOps::channels() const
{
- unsigned int val;
- int err;
-
- int AudioSystemChannels;
-
- if (!mHandle)
- return -1;
-
- err = snd_pcm_hw_params_get_channels(mHardwareParams, &val);
- if (err < 0) {
- LOGE("Unable to get device channel count: %s",
- snd_strerror(err));
- return -1;
- }
-
- AudioSystemChannels = AudioSystem::DEFAULT;
-
- switch(val){
- case 1:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_FRONT_RIGHT;
- break;
- case 2:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_STEREO;
- break;
- case 4:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_QUAD;
- break;
- case 6:
- AudioSystemChannels = AudioSystem::CHANNEL_OUT_5POINT1;
- break;
- defualt:
- LOGE("FATAL: AudioSystem does not support %d channels.", val);
- }
-
+ return getAndroidChannels(mDefaults->channelCount);
+}
- return AudioSystemChannels;
+int ALSAStreamOps::channelCount() const
+{
+ return mDefaults->channelCount;
}
-status_t ALSAStreamOps::channelCount(int channels) {
+status_t ALSAStreamOps::channelCount(int channelCount) {
int err;
if (!mHandle)
return NO_INIT;
- // if(channels == 1) channels = 2; //Kamat: This is a fix added to avoid audioflinger crash (current audio driver does not support mono). Please check and modify suitably later.
+ // if(channelCount == 1) channelCount = 2; //Kamat: This is a fix added to avoid audioflinger crash (current audio driver does not support mono). Please check and modify suitably later.
- err = snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, channels);
+ err = snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, channelCount);
if (err < 0) {
LOGE("Unable to set channel count to %i: %s",
- channels, snd_strerror(err));
+ channelCount, snd_strerror(err));
return BAD_VALUE;
}
LOGD("Using %i %s for %s.",
- channels, channels == 1 ? "channel" : "channels", streamName());
+ channelCount, channelCount == 1 ? "channel" : "channels", streamName());
return NO_ERROR;
}
@@ -1204,14 +1212,14 @@ status_t ALSAStreamOps::setDevice(int mode, uint32_t device, uint audio_mode)
// is queried before it has been set. i.e. calling channelCount()
// before channelCount(channels) may return -EINVAL.
//
- status = channelCount(mDefaults->channels);
+ status = channelCount(mDefaults->channelCount);
if (status != NO_ERROR)
return status;
// Don't check for failure; some devices do not support the default
// sample rate.
-
- sampleRate(mDefaults->sampleRate);
+ // FIXME:: always use default sampling rate
+ sampleRate(DEFAULT_SAMPLE_RATE);
// Disable hardware resampling.
status = setHardwareResample(false);
@@ -1219,6 +1227,8 @@ status_t ALSAStreamOps::setDevice(int mode, uint32_t device, uint audio_mode)
return status;
snd_pcm_uframes_t bufferSize = mDefaults->bufferSize;
+ snd_pcm_uframes_t periodSize = mDefaults->periodSize;
+ period_val = bufferSize/periodSize;
unsigned int latency = mDefaults->latency;
@@ -1230,67 +1240,98 @@ status_t ALSAStreamOps::setDevice(int mode, uint32_t device, uint audio_mode)
return NO_INIT;
}
- // Setup buffers for latency
- err = snd_pcm_hw_params_set_buffer_time_near (mHandle, mHardwareParams,
- &latency, NULL);
- if(audio_mode == PLAYBACK) {
- period_val = PERIOD_PLAYBACK;
- if(snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, period_val, 0) < 0)
- LOGE("Fail to set period size %d for playback", period_val);
- }
- else
- period_val = PERIOD_CAPTURE;
-
- if (err < 0) {
- /* That didn't work, set the period instead */
- unsigned int periodTime = latency / period_val;
- err = snd_pcm_hw_params_set_period_time_near (mHandle, mHardwareParams,
- &periodTime, NULL);
- if (err < 0) {
- LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
- return NO_INIT;
- }
- snd_pcm_uframes_t periodSize;
- err = snd_pcm_hw_params_get_period_size (mHardwareParams, &periodSize, NULL);
- if (err < 0) {
- LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
- return NO_INIT;
- }
- bufferSize = periodSize * period_val;
- if (bufferSize < mDefaults->bufferSize)
- bufferSize = mDefaults->bufferSize;
- err = snd_pcm_hw_params_set_buffer_size_near (mHandle, mHardwareParams, &bufferSize);
- if (err < 0) {
- LOGE("Unable to set the buffer size for latency: %s", snd_strerror(err));
- return NO_INIT;
- }
- } else {
- // OK, we got buffer time near what we expect. See what that did for bufferSize.
- err = snd_pcm_hw_params_get_buffer_size (mHardwareParams, &bufferSize);
- if (err < 0) {
- LOGE("Unable to get the buffer size for latency: %s", snd_strerror(err));
- return NO_INIT;
- }
- // Does set_buffer_time_near change the passed value? It should.
- err = snd_pcm_hw_params_get_buffer_time (mHardwareParams, &latency, NULL);
- if (err < 0) {
- LOGE("Unable to get the buffer time for latency: %s", snd_strerror(err));
- return NO_INIT;
- }
- unsigned int periodTime = latency / period_val;
- err = snd_pcm_hw_params_set_period_time_near (mHandle, mHardwareParams,
- &periodTime, NULL);
- if (err < 0) {
- LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
+// if(audio_mode == PLAYBACK) {
+// period_val = PERIODS_PLAYBACK;
+// }
+// else {
+// period_val = PERIODS_CAPTURE;
+// }
+ // not working for capture ?
+ if (mDefaults->direction == SND_PCM_STREAM_PLAYBACK) {
+ if(snd_pcm_hw_params_set_periods(mHandle, mHardwareParams,
+ period_val, mDefaults->direction) < 0) {
+ LOGE("Fail to set period size %d for %d direction",
+ period_val, mDefaults->direction);
return NO_INIT;
}
}
+ err = snd_pcm_hw_params_get_period_size (mHardwareParams, &periodSize, NULL);
+ if (err < 0) {
+ LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
+ return NO_INIT;
+ }
+
+// // Setup buffers for latency
+// err = snd_pcm_hw_params_set_buffer_time_near (mHandle, mHardwareParams,
+// &latency, NULL);
+// if(audio_mode == PLAYBACK) {
+// period_val = PERIODS_PLAYBACK;
+// if(snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, period_val, 0) < 0)
+// LOGE("Fail to set period size %d for playback", period_val);
+// }
+// else
+// period_val = PERIODS_CAPTURE;
+//
+// if (err < 0) {
+// LOGD("snd_pcm_hw_params_set_buffer_time_near() failed: %s", snd_strerror(err));
+// /* That didn't work, set the period instead */
+// unsigned int periodTime = latency / period_val;
+// err = snd_pcm_hw_params_set_period_time_near (mHandle, mHardwareParams,
+// &periodTime, NULL);
+// if (err < 0) {
+// LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// err = snd_pcm_hw_params_get_period_size (mHardwareParams, &periodSize, NULL);
+// if (err < 0) {
+// LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// bufferSize = periodSize * period_val;
+// if (bufferSize < mDefaults->bufferSize)
+// bufferSize = mDefaults->bufferSize;
+// err = snd_pcm_hw_params_set_buffer_size_near (mHandle, mHardwareParams, &bufferSize);
+// if (err < 0) {
+// LOGE("Unable to set the buffer size for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// } else {
+// LOGD("snd_pcm_hw_params_set_buffer_time_near() OK");
+// // OK, we got buffer time near what we expect. See what that did for bufferSize.
+// err = snd_pcm_hw_params_get_buffer_size (mHardwareParams, &bufferSize);
+// if (err < 0) {
+// LOGE("Unable to get the buffer size for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// // Does set_buffer_time_near change the passed value? It should.
+// err = snd_pcm_hw_params_get_buffer_time (mHardwareParams, &latency, NULL);
+// if (err < 0) {
+// LOGE("Unable to get the buffer time for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// LOGD("got latency %d for bufferSize %d", latency, bufferSize);
+// unsigned int periodTime = latency / period_val;
+// LOGD("got latency %d for bufferSize %d => periodTime %d", latency, bufferSize, periodTime);
+// err = snd_pcm_hw_params_set_period_time_near (mHandle, mHardwareParams,
+// &periodTime, NULL);
+// if (err < 0) {
+// LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// err = snd_pcm_hw_params_get_period_size (mHardwareParams, &periodSize, NULL);
+// if (err < 0) {
+// LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
+// return NO_INIT;
+// }
+// }
LOGD("Buffer size: %d", (int)bufferSize);
+ LOGD("Period size: %d", (int)periodSize);
LOGD("Latency: %d", (int)latency);
mDefaults->bufferSize = bufferSize;
mDefaults->latency = latency;
+ mDefaults->periodSize = periodSize;
// Commit the hardware parameters back to the device.
err = snd_pcm_hw_params(mHandle, mHardwareParams);
@@ -1348,10 +1389,12 @@ AudioStreamOutALSA::AudioStreamOutALSA(AudioHardwareALSA *parent) :
devicePrefix : "AndroidPlayback",
direction : SND_PCM_STREAM_PLAYBACK,
format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
- channels : 2,
+ channelCount : 2,
sampleRate : DEFAULT_SAMPLE_RATE,
- latency : 250000, // Desired Delay in usec
- bufferSize : 4096, // Desired Number of samples
+ smpRateShift : 0,
+ latency : LATENCY_PLAYBACK_MS, // Desired Delay in usec
+ bufferSize : BUFFER_SZ_PLAYBACK, // Desired Number of samples
+ periodSize : PERIOD_SZ_PLAYBACK
};
setStreamDefaults(&_defaults);
@@ -1363,16 +1406,6 @@ AudioStreamOutALSA::~AudioStreamOutALSA()
mParent->mOutput = NULL;
}
-//int AudioStreamOutALSA::channelCount() const
-uint32_t AudioStreamOutALSA::channels() const
-{
- uint32_t c = ALSAStreamOps::channelCount();
-
- // AudioMixer will seg fault if it doesn't have two channels.
- LOGW_IF(c != AudioSystem::CHANNEL_OUT_STEREO,
- "AudioMixer expects two channels, but only %i found!", c);
- return c;
-}
/* New arch */
status_t AudioStreamOutALSA::setVolume(float left, float right)
@@ -1380,7 +1413,7 @@ status_t AudioStreamOutALSA::setVolume(float left, float right)
if (! mParent->mMixer || ! mDevice)
return NO_INIT;
- /** Tushar - Need to decide on the volume value
+ /** Tushar - Need to decide on the volume value
* that we pass onto the mixer. */
return mParent->mMixer->setVolume (mDevice, (left + right)/2);
}
@@ -1402,24 +1435,24 @@ status_t AudioStreamOutALSA::setParameters(const String8& keyValuePairs)
int device;
int value;
LOGD("AudioStreamOutALSA::setParameters() %s", keyValuePairs.string());
-
- if (param.getInt(String8(AudioParameter::keyRouting), device) == NO_ERROR)
+
+ if (param.getInt(String8(AudioParameter::keyRouting), device) == NO_ERROR)
{
mDevice = device;
- if (mParent->mInput) mParent->mInput->mDevice = device;
- mParent->mRoutes[mParent->mMode] = mDevice;
+// if (mParent->mInput) mParent->mInput->mDevice = device;
+ mParent->mRoutes[mParent->mMode] = mDevice;
mParent->doRouting(mDevice);
param.remove(String8(AudioParameter::keyRouting));
}
else if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR)
{
- mParent->mOutput->mDefaults->sampleRate = value;
- mParent->doRouting(mDevice);
- param.remove(String8(AudioParameter::keySamplingRate));
+ mParent->mOutput->mDefaults->sampleRate = value;
+ mParent->doRouting(mDevice);
+ param.remove(String8(AudioParameter::keySamplingRate));
}
-
+
if (param.size()) {
status = BAD_VALUE;
}
@@ -1435,7 +1468,7 @@ status_t AudioStreamOutALSA::setParameters(const String8& keyValuePairs)
int device = keyValuePairs.string()[keyValuePairs.length()-1] - 48 -1 ; //easy conversion frm ascii to int and then to required number
LOGV("\n\n-------->> ALSA SET PARAMS device %d \n\n",(1<<device));
mParent->mOutput->setDevice(mMode, 1<<device, PLAYBACK);
- return NO_ERROR;
+ return NO_ERROR;
#endif
}
String8 AudioStreamOutALSA::getParameters(const String8& keys)
@@ -1444,16 +1477,16 @@ String8 AudioStreamOutALSA::getParameters(const String8& keys)
AudioParameter param = AudioParameter(keys);
String8 value;
String8 key = String8(AudioParameter::keyRouting);
-
+
if (param.get(key, value) == NO_ERROR) {
param.addInt(key, (int)mDevice);
}
-
+
LOGD("AudioStreamOutALSA::getParameters() %s", param.toString().string());
return param.toString();
#else
/* TODO: Implement as per new arch */
- return keys;
+ return keys;
#endif
}
@@ -1474,7 +1507,8 @@ ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
AutoMutex lock(mLock);
if (!mPowerLock) {
- ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
+ LOGD("Calling setDevice from write @..%d.\n",__LINE__);
+ ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock");
mPowerLock = true;
}
@@ -1485,36 +1519,29 @@ ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
fwrite(buffer, bytes, 1, fpOutput);
LOGD("Output PCM dumped!!");
#endif
- if (!mHandle){
- LOGD("Calling setDevice from write @..%d.\n",__LINE__);
- ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
- }
do {
- // write correct number of bytes per attempt
- n = snd_pcm_writei(mHandle,
- (char *)buffer + sent,
- snd_pcm_bytes_to_frames(mHandle, bytes-sent));
+ // write correct number of bytes per attempt
+ n = snd_pcm_writei(mHandle, (char *) buffer + sent, snd_pcm_bytes_to_frames(mHandle, bytes
+ - sent));
if (n == -EBADFD) {
- LOGD("Calling setDevice.. pcm_write returned error @..%d.\n",__LINE__);
- // Somehow the stream is in a bad state. The driver probably
- // has a bug and snd_pcm_recover() doesn't seem to handle this.
- ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
- }
- else if (n < 0) {
+ LOGD("Calling setDevice.. pcm_write returned error @..%d.\n",__LINE__);
+ // Somehow the stream is in a bad state. The driver probably
+ // has a bug and snd_pcm_recover() doesn't seem to handle this.
+ ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
+ } else if (n < 0) {
if (mHandle) {
- // snd_pcm_recover() will return 0 if successful in recovering from
- // // an error, or -errno if the error was unrecoverable.
- // We can make silent bit on as we are now handling the under-run and there will not be any data loss due to under-run
- n = snd_pcm_recover(mHandle, n, 1);
- if (n)
- return static_cast<ssize_t>(n);
+ // snd_pcm_recover() will return 0 if successful in recovering from
+ // // an error, or -errno if the error was unrecoverable.
+ // We can make silent bit on as we are now handling the under-run and there will not be any data loss due to under-run
+ n = snd_pcm_recover(mHandle, n, 1);
+ if (n)
+ return static_cast<ssize_t> (n);
}
- }
- else
- sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle, n));
+ } else
+ sent += static_cast<ssize_t> (snd_pcm_frames_to_bytes(mHandle, n));
} while (mHandle && sent < bytes);
//LOGI("Request Bytes=%d, Actual Written=%d",bytes,sent);
- return sent;
+ return snd_pcm_frames_to_bytes(mHandle, sent);
}
#else
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
@@ -1532,14 +1559,16 @@ ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
ALSAStreamOps::setDevice(mMode, mDevice,PLAYBACK);
mPowerLock = true;
}
-
+ if (!mHandle) {
+ return -1;
+ }
n = snd_pcm_writei(mHandle,
buffer,
snd_pcm_bytes_to_frames(mHandle, bytes));
if (n < 0 && mHandle) {
// snd_pcm_recover() will return 0 if successful in recovering from
// an error, or -errno if the error was unrecoverable.
- //device driver sometimes does not recover -vladi
+ //device driver sometimes does not recover -vladi
n = snd_pcm_recover(mHandle, n, 0);
if(n < 0) //if recover fails
ALSAStreamOps::setDevice(mMode, mDevice, PLAYBACK);
@@ -1563,32 +1592,37 @@ status_t AudioStreamOutALSA::setDevice(int mode, uint32_t newDevice, uint32_t au
return ALSAStreamOps::setDevice(mode, newDevice, audio_mode);
}
-status_t AudioStreamOutALSA::standby()
-{
+status_t AudioStreamOutALSA::standby() {
AutoMutex lock(mLock);
LOGD("Inside AudioStreamOutALSA::standby\n");
if (mHandle)
- snd_pcm_drain (mHandle);
+ snd_pcm_drain ( mHandle);
if (mPowerLock) {
- if(!mParent->mActivatedInputDevice){ // Let PCM device alive on activating input stream.
- snd_pcm_close(mHandle);
- mHandle = NULL;
+ if (!mParent->mActivatedInputDevice) { // Let PCM device alive on activating input stream.
+ snd_pcm_close( mHandle);
+ mHandle = NULL;
#if 1 // Fix for underrun error
- release_wake_lock ("AudioOutLock");
+ release_wake_lock("AudioOutLock");
#else
- release_wake_lock ("AudioLock");
+ release_wake_lock ("AudioLock");
#endif
- mPowerLock = false;
- }
- }
-// close(); //Don't call this as this function will reset the mode also
+ mPowerLock = false;
+ }
+ }
+ // close(); //Don't call this as this function will reset the mode also
return NO_ERROR;
}
bool AudioStreamOutALSA::isStandby()
{
- return (!mHandle);
+ return (!mPowerLock);
+}
+
+void AudioStreamOutALSA::setWakeLock()
+{
+ acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock");
+ mPowerLock = true;
}
#define USEC_TO_MSEC(x) ((x + 999) / 1000)
@@ -1609,10 +1643,12 @@ AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent) :
devicePrefix : "AndroidRecord",
direction : SND_PCM_STREAM_CAPTURE,
format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
- channels : 1,
- sampleRate : AudioRecord::DEFAULT_SAMPLE_RATE,
- latency : 250000, // Desired Delay in usec
- bufferSize : 4096, // Desired Number of samples
+ channelCount : 1,
+ sampleRate : DEFAULT_SAMPLE_RATE,
+ smpRateShift : 0,
+ latency : LATENCY_CAPTURE_MS,// Desired Delay in usec
+ bufferSize : BUFFER_SZ_CAPTURE, // Desired Number of samples
+ periodSize : PERIOD_SZ_CAPTURE
};
setStreamDefaults(&_defaults);
@@ -1620,12 +1656,7 @@ AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent) :
AudioStreamInALSA::~AudioStreamInALSA()
{
- if (mPowerLock) {
- snd_pcm_close(mHandle);
- mHandle = NULL;
- release_wake_lock ("AudioInLock");
- mPowerLock = false;
- }
+ standby_l();
mParent->mInput = NULL;
}
@@ -1646,29 +1677,69 @@ ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes)
if (!mPowerLock) {
acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock");
-
+
#ifdef PCM_INPUT_DUMP
fwrite(buffer, readBytes, 1, fpInput);
LOGD("Input PCM dumped!!");
#endif
+#if defined TURN_ON_DEVICE_ONLY_USE
+ mParent->mActivatedInputDevice = true;
+// setMicStatus(1);
+#endif
LOGD("Calling setDevice from read@..%d.\n",__LINE__);
ALSAStreamOps::setDevice(mMode, mDevice,CAPTURE);
mPowerLock = true;
}
- n = snd_pcm_readi(mHandle,
- buffer,
- snd_pcm_bytes_to_frames(mHandle, bytes));
- if (n < 0 && mHandle) {
- n = snd_pcm_recover(mHandle, n, 0);
+ if (!mHandle) {
+ return -1;
+ }
+
+ // FIXME: only support reads of exactly bufferSize() for now
+ if (bytes != bufferSize()) {
+ LOGW("AudioStreamInALSA::read bad read size %d expected %d", bytes, bufferSize());
+ return -1;
}
+ size_t frames = snd_pcm_bytes_to_frames(mHandle, bytes);
+ uint32_t shift = mDefaults->smpRateShift;
+ do {
+ n = snd_pcm_readi(mHandle,
+ (uint8_t *)mBuffer,
+ frames << shift);
+ if (n < 0) {
+ LOGD("AudioStreamInALSA::read error %d", n);
+ n = snd_pcm_recover(mHandle, n, 0);
+ LOGD("AudioStreamInALSA::snd_pcm_recover error %d", n);
+ if (n)
+ return static_cast<ssize_t> (n);
+ } else {
+ n >>= shift;
+ }
+ } while (n == 0);
+
+ // FIXME: quick hack to enable simultaneous playback and record. input and output device
+ // drivers always operate at 44.1kHz. We do a dirty downsampling here by an entire ratio
+ // (4, 2 or 1) without filtering and the resampler in AudioFlinger does the remaining
+ // resampling if any (e.g. 11025 -> 8000). We do this because of the limitation of the
+ // downsampler in AudioFlinger (SR in < 2 * SR out)
+ int16_t *out = (int16_t *)buffer;
+ if (mDefaults->channelCount == 1) {
+ for (size_t i = 0; i < n; i++) {
+ out[i] = mBuffer[i << shift];
+ }
+ } else {
+ for (size_t i = 0; i < n; i++) {
+ out[i] = mBuffer[i << shift];
+ out[i + 1] = mBuffer[(i << shift) + 1];
+ }
+ }
#ifdef PCM_INPUT_DUMP
fwrite(buffer, bytes, 1, fpInput);
LOGD("Input PCM dumped!!");
#endif
- return static_cast<ssize_t>(n);
+ return snd_pcm_frames_to_bytes(mHandle, n);
}
status_t AudioStreamInALSA::dump(int fd, const Vector<String16>& args)
@@ -1687,10 +1758,16 @@ status_t AudioStreamInALSA::standby()
{
AutoMutex lock(mLock);
+ return standby_l();
+}
+
+status_t AudioStreamInALSA::standby_l()
+{
LOGD("Entering AudioStreamInALSA::standby\n");
if (mPowerLock) {
mParent->mActivatedInputDevice = false;
snd_pcm_close(mHandle);
+ LOGD("AudioStreamInALSA::standby snd_pcm_close()");
mHandle = NULL;
release_wake_lock ("AudioInLock");
mPowerLock = false;
@@ -1699,6 +1776,12 @@ status_t AudioStreamInALSA::standby()
return NO_ERROR;
}
+void AudioStreamInALSA::setWakeLock()
+{
+ acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock");
+ mPowerLock = true;
+}
+
/* New Arch */
status_t AudioStreamInALSA::setParameters(const String8& keyValuePairs)
{
@@ -1708,14 +1791,14 @@ status_t AudioStreamInALSA::setParameters(const String8& keyValuePairs)
status_t status = NO_ERROR;
int device;
LOGD("AudioStreamInALSA::setParameters() %s", keyValuePairs.string());
-
+
if (param.getInt(key, device) == NO_ERROR) {
- mDevice = device;
- if(mDevice != 0)
- setDevice(mMode, mDevice, CAPTURE);
- param.remove(key);
+ mDevice = device;
+ if(mPowerLock && mDevice != 0)
+ setDevice(mMode, mDevice, CAPTURE);
+ param.remove(key);
}
-
+
if (param.size()) {
status = BAD_VALUE;
}
@@ -1743,11 +1826,11 @@ String8 AudioStreamInALSA::getParameters(const String8& keys)
AudioParameter param = AudioParameter(keys);
String8 value;
String8 key = String8(AudioParameter::keyRouting);
-
+
if (param.get(key, value) == NO_ERROR) {
param.addInt(key, (int)mDevice);
}
-
+
LOGD("AudioStreamInALSA::getParameters() %s", param.toString().string());
return param.toString();
#else
@@ -2139,7 +2222,7 @@ status_t ALSAControl::get(const char *name, unsigned int &value, int index)
snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_info_alloca(&info);
snd_ctl_elem_value_alloca(&control);
-
+
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(id, name);
snd_ctl_elem_info_set_id(info, id);
@@ -2191,7 +2274,7 @@ status_t ALSAControl::set(const char *name, unsigned int value, int index)
snd_ctl_elem_id_alloca(&id);
snd_ctl_elem_info_alloca(&info);
snd_ctl_elem_value_alloca(&control);
-
+
snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(id, name);
snd_ctl_elem_info_set_id(info, id);
@@ -2299,7 +2382,7 @@ status_t AudioHardwareIPC::transmitVolumeIPC(uint32_t type, float volume)
memset(data, 0, 100);
data[0] = OEM_FUNCTION_ID_SOUND;
data[1] = OEM_SOUND_SET_VOLUME_CTRL;
- data[2] = 0x00; // data length
+ data[2] = 0x00; // data length
data[3] = 0x06; // data length
data[4] = type; // volume type
data[5] = level; // volume level
@@ -2327,7 +2410,7 @@ status_t AudioHardwareIPC::transmitAudioPathIPC(uint32_t path)
memset(data, 0, 100);
data[0] = OEM_FUNCTION_ID_SOUND;
data[1] = OEM_SOUND_SET_AUDIO_PATH_CTRL;
- data[2] = 0x00; // data length
+ data[2] = 0x00; // data length
data[3] = 0x05; // data length
data[4] = path; // audio path
@@ -2357,12 +2440,12 @@ status_t AudioHardwareIPC::transmitClock_IPC(uint32_t condition)
memset(data, 0, 100);
data[0] = OEM_FUNCTION_ID_SOUND;
data[1] = OEM_SOUND_SET_CLOCK_CTRL;
- data[2] = 0x00; // data length
+ data[2] = 0x00; // data length
data[3] = 0x05; // data length
- data[4] = condition;
+ data[4] = condition;
ret = InvokeOemRequestHookRaw(mClient, data, 5); //sizeof(data));
-
+
if (ret != RIL_CLIENT_ERR_AGAIN && ret != RIL_CLIENT_ERR_SUCCESS){
LOGE("[*] InvokeOemRequestHookRaw() error ret = %d\n", ret);
return INVALID_OPERATION;
diff --git a/libaudio/AudioHardwareALSA.h b/libaudio/AudioHardwareALSA.h
index 5a4b5d5..0390beb 100755
--- a/libaudio/AudioHardwareALSA.h
+++ b/libaudio/AudioHardwareALSA.h
@@ -90,9 +90,29 @@
#define OEM_SOUND_TYPE_HEADSET 0x31 // Headset (0x30) + Voice(0x01)
#define OEM_SOUND_TYPE_BTVOICE 0x41 // BT(0x40) + Voice(0x01)
#endif
+
+#ifndef ALSA_DEFAULT_SAMPLE_RATE
+#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
+#endif
+
+#define DEFAULT_SAMPLE_RATE ALSA_DEFAULT_SAMPLE_RATE
+
+#define PLAYBACK 0
+#define PERIOD_SZ_PLAYBACK 1024
+#define PERIODS_PLAYBACK 4
+#define BUFFER_SZ_PLAYBACK (PERIODS_PLAYBACK * PERIOD_SZ_PLAYBACK)
+#define LATENCY_PLAYBACK_MS ((BUFFER_SZ_PLAYBACK * 1000 / DEFAULT_SAMPLE_RATE) * 1000)
+
+#define CAPTURE 1
+#define PERIOD_SZ_CAPTURE 2048
+#define PERIODS_CAPTURE 2
+#define BUFFER_SZ_CAPTURE (PERIODS_CAPTURE * PERIOD_SZ_CAPTURE)
+#define LATENCY_CAPTURE_MS ((BUFFER_SZ_CAPTURE * 1000 / DEFAULT_SAMPLE_RATE) * 1000)
+
namespace android
{
+
class AudioHardwareALSA;
// ----------------------------------------------------------------------------
@@ -143,10 +163,12 @@ namespace android
const char * devicePrefix;
snd_pcm_stream_t direction; // playback or capture
snd_pcm_format_t format;
- int channels;
+ int channelCount;
uint32_t sampleRate;
+ uint32_t smpRateShift;
unsigned int latency; // Delay in usec
unsigned int bufferSize; // Size of sample buffer
+ unsigned int periodSize; // Size of sample buffer
};
ALSAStreamOps();
@@ -159,11 +181,12 @@ namespace android
status_t sampleRate(uint32_t rate);
virtual size_t bufferSize() const;
virtual int format() const;
- int getAndroidFormat(snd_pcm_format_t format);
+ int getAndroidFormat(snd_pcm_format_t format);
- virtual int channelCount() const;
- status_t channelCount(int channels);
- uint32_t getAndroidChannels(int channels);
+ virtual uint32_t channels() const;
+ int channelCount() const;
+ status_t channelCount(int channelCount);
+ uint32_t getAndroidChannels(int channelCount) const;
status_t open(int mode, uint32_t device);
void close();
@@ -201,14 +224,13 @@ namespace android
virtual ~AudioStreamOutALSA();
- status_t set(int *format,
- uint32_t *channelCount,
- uint32_t *sampleRate){
- return ALSAStreamOps::set(format, channelCount, sampleRate);
- }
+ status_t set(int *format,
+ uint32_t *channelCount,
+ uint32_t *sampleRate){
+ return ALSAStreamOps::set(format, channelCount, sampleRate);
+ }
- virtual uint32_t sampleRate() const
- {
+ virtual uint32_t sampleRate() const {
return ALSAStreamOps::sampleRate();
}
@@ -217,8 +239,10 @@ namespace android
return ALSAStreamOps::bufferSize();
}
- //virtual int channelCount() const;
- virtual uint32_t channels() const;
+ virtual uint32_t channels() const
+ {
+ return ALSAStreamOps::channels();
+ }
virtual int format() const
{
@@ -236,6 +260,7 @@ namespace android
status_t standby();
bool isStandby();
+ void setWakeLock();
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
@@ -254,13 +279,12 @@ namespace android
AudioStreamInALSA(AudioHardwareALSA *parent);
virtual ~AudioStreamInALSA();
- status_t set(int *format,
- uint32_t *channelCount,
- uint32_t *sampleRate){
- return ALSAStreamOps::set(format, channelCount, sampleRate);
- }
+ status_t set(int *format,
+ uint32_t *channelCount,
+ uint32_t *sampleRate){
+ return ALSAStreamOps::set(format, channelCount, sampleRate);
+ }
- //virtual uint32_t sampleRate() {
virtual uint32_t sampleRate() const {
return ALSAStreamOps::sampleRate();
}
@@ -270,10 +294,9 @@ namespace android
return ALSAStreamOps::bufferSize();
}
- //virtual int channelCount() const
virtual uint32_t channels() const
{
- return ALSAStreamOps::channelCount();
+ return ALSAStreamOps::channels();
}
virtual int format() const
@@ -288,6 +311,8 @@ namespace android
virtual status_t setGain(float gain);
virtual status_t standby();
+ status_t standby_l();
+ void setWakeLock();
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
@@ -297,6 +322,7 @@ namespace android
private:
AudioHardwareALSA *mParent;
bool mPowerLock;
+ int16_t mBuffer[2 * PERIOD_SZ_CAPTURE];
};
#if defined SEC_IPC
@@ -373,7 +399,8 @@ namespace android
AudioSystem::audio_in_acoustics acoustics);
virtual void closeInputStream(AudioStreamIn* in);
-
+ static uint32_t checkInputSampleRate(uint32_t sampleRate);
+ static const uint32_t inputSamplingRates[];
protected:
/**