blob: c3b6caa5c95b37fa72915c861ccff90d636c8eef [file] [log] [blame]
/* AudioHardwareALSA.h
**
** Copyright 2008, Wind River Systems
**
** 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.
*/
#ifndef ANDROID_AUDIO_HARDWARE_ALSA_H
#define ANDROID_AUDIO_HARDWARE_ALSA_H
#include <stdint.h>
#include <sys/types.h>
#include <alsa/asoundlib.h>
#include <hardware_legacy/AudioHardwareBase.h>
// sangsu fix : headers for IPC
#include "secril-client.h"
#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 1024
#define PERIODS_CAPTURE 4
#define BUFFER_SZ_CAPTURE (PERIODS_CAPTURE * PERIOD_SZ_CAPTURE)
#define LATENCY_CAPTURE_MS ((BUFFER_SZ_CAPTURE * 1000 / DEFAULT_SAMPLE_RATE) * 1000)
//Recognition param
#define RECOGNITION_OFF 0
#define RECOGNITION_ON 1
namespace android
{
class AudioHardwareALSA;
// ----------------------------------------------------------------------------
class ALSAMixer
{
public:
ALSAMixer();
virtual ~ALSAMixer();
bool isValid() { return !!mMixer[SND_PCM_STREAM_PLAYBACK]; }
status_t setMasterVolume(float volume);
status_t setMasterGain(float gain);
status_t setVolume(uint32_t device, float volume);
status_t setGain(uint32_t device, float gain);
status_t setCaptureMuteState(uint32_t device, bool state);
status_t getCaptureMuteState(uint32_t device, bool *state);
status_t setPlaybackMuteState(uint32_t device, bool state);
status_t getPlaybackMuteState(uint32_t device, bool *state);
private:
snd_mixer_t *mMixer[SND_PCM_STREAM_LAST+1];
};
class ALSAControl
{
public:
ALSAControl(const char *device = "default");
virtual ~ALSAControl();
status_t get(const char *name, unsigned int &value, int index = 0);
status_t set(const char *name, unsigned int value, int index = -1);
private:
snd_ctl_t *mHandle;
};
class ALSAStreamOps
{
public:
uint32_t device() { return mDevice; }
void close();
protected:
friend class AudioStreamOutALSA;
friend class AudioStreamInALSA;
struct StreamDefaults
{
const char * devicePrefix;
snd_pcm_stream_t direction; // playback or capture
snd_pcm_format_t format;
int channelCount;
uint32_t sampleRate;
uint32_t bufferRatio;
unsigned int latency; // Delay in usec
unsigned int bufferSize; // Size of sample buffer
unsigned int periodSize; // Size of sample buffer
};
ALSAStreamOps();
virtual ~ALSAStreamOps();
status_t set(int *format,
uint32_t *channels,
uint32_t *rate);
virtual uint32_t sampleRate() const;
status_t sampleRate(uint32_t rate);
virtual size_t bufferSize() const;
virtual int format() const;
int getAndroidFormat(snd_pcm_format_t format);
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);
status_t setSoftwareParams();
status_t setPCMFormat(snd_pcm_format_t format);
status_t setHardwareResample(bool resample);
const char *streamName();
status_t setDevice(int mode, uint32_t device, uint32_t audio_mode);
const char *deviceName(int mode, uint32_t device);
void setStreamDefaults(StreamDefaults *dev) {
mDefaults = dev;
}
Mutex mLock;
private:
snd_pcm_t *mHandle;
snd_pcm_hw_params_t *mHardwareParams;
snd_pcm_sw_params_t *mSoftwareParams;
uint32_t mDevice;
StreamDefaults *mDefaults;
};
// ----------------------------------------------------------------------------
class AudioStreamOutALSA : public AudioStreamOut, public ALSAStreamOps
{
public:
AudioStreamOutALSA(AudioHardwareALSA *parent);
virtual ~AudioStreamOutALSA();
status_t set(int *format,
uint32_t *channelCount,
uint32_t *sampleRate){
return ALSAStreamOps::set(format, channelCount, sampleRate);
}
virtual uint32_t sampleRate() const {
return ALSAStreamOps::sampleRate();
}
virtual size_t bufferSize() const
{
return ALSAStreamOps::bufferSize();
}
virtual uint32_t channels() const
{
return ALSAStreamOps::channels();
}
virtual int format() const
{
return ALSAStreamOps::format();
}
virtual uint32_t latency() const;
virtual ssize_t write(const void *buffer, size_t bytes);
virtual status_t dump(int fd, const Vector<String16>& args);
status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode,
bool force = false);
virtual status_t setVolume(float left, float right); //Tushar: New arch
status_t setVolume(float volume);
status_t standby();
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
virtual status_t getRenderPosition(uint32_t *dspFrames);
bool isActive() { return mPowerLock; }
private:
AudioHardwareALSA *mParent;
bool mPowerLock;
};
class ALSADownsampler;
class ALSABufferProvider
{
public:
struct Buffer {
union {
void* raw;
short* i16;
int8_t* i8;
};
size_t frameCount;
};
virtual ~ALSABufferProvider() {}
virtual status_t getNextBuffer(Buffer* buffer) = 0;
virtual void releaseBuffer(Buffer* buffer) = 0;
};
class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps, public ALSABufferProvider
{
public:
AudioStreamInALSA(AudioHardwareALSA *parent);
virtual ~AudioStreamInALSA();
status_t set(int *format,
uint32_t *channelCount,
uint32_t *sampleRate);
virtual uint32_t sampleRate() const {
return ALSAStreamOps::sampleRate();
}
virtual size_t bufferSize() const
{
return ALSAStreamOps::bufferSize();
}
virtual uint32_t channels() const
{
return ALSAStreamOps::channels();
}
virtual int format() const
{
return ALSAStreamOps::format();
}
virtual ssize_t read(void* buffer, ssize_t bytes);
virtual status_t dump(int fd, const Vector<String16>& args);
status_t setDevice(int mode, uint32_t newDevice, uint32_t audio_mode,
bool force = false);
virtual status_t setGain(float gain);
virtual status_t standby();
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
virtual unsigned int getInputFramesLost() const { return 0; }
bool isActive() { return mPowerLock; }
// ALSABufferProvider
virtual status_t getNextBuffer(ALSABufferProvider::Buffer* buffer);
virtual void releaseBuffer(ALSABufferProvider::Buffer* buffer);
private:
AudioHardwareALSA *mParent;
bool mPowerLock;
ALSADownsampler *mDownSampler;
status_t mReadStatus;
size_t mInPcmInBuf;
int16_t *mPcmIn;
};
class AudioHardwareALSA : public AudioHardwareBase
{
public:
AudioHardwareALSA();
virtual ~AudioHardwareALSA();
/**
* check to see if the audio hardware interface has been initialized.
* return status based on values defined in include/utils/Errors.h
*/
virtual status_t initCheck();
/** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
virtual status_t setVoiceVolume(float volume);
virtual status_t setMode(int mode);
/**
* set the audio volume for all audio activities other than voice call.
* Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
* the software mixer will emulate this capability.
*/
virtual status_t setMasterVolume(float volume);
// mic mute
virtual status_t setMicMute(bool state);
virtual status_t getMicMute(bool* state);
virtual size_t getInputBufferSize(uint32_t sampleRate,
int format,
int channelCount);
/** This method creates and opens the audio hardware output stream */
virtual AudioStreamOut* openOutputStream(uint32_t devices,
int *format = 0,
uint32_t *channels = 0,
uint32_t *sampleRate = 0,
status_t *status = 0);
virtual void closeOutputStream(AudioStreamOut* out);
/** This method creates and opens the audio hardware input stream */
virtual AudioStreamIn* openInputStream(uint32_t devices,
int *format,
uint32_t *channels,
uint32_t *sampleRate,
status_t *status,
AudioSystem::audio_in_acoustics acoustics);
virtual void closeInputStream(AudioStreamIn* in);
static uint32_t checkInputSampleRate(uint32_t sampleRate);
static const uint32_t inputSamplingRates[];
static uint32_t bufferRatio(uint32_t samplingRate);
int mode() { return mMode; }
Mutex& lock() { return mLock; }
int setVoiceRecordGain(bool enable);
int setVoiceRecordGain_l(bool enable);
virtual status_t setParameters(const String8& keyValuePairs);
protected:
/**
* doRouting actually initiates the routing. A call to setRouting
* or setMode may result in a routing change. The generic logic calls
* doRouting when required. If the device has any special requirements these
* methods can be overriden.
*/
status_t doRouting(uint32_t device, bool force = false);
status_t doRouting_l(uint32_t device, bool force = false);
virtual status_t dump(int fd, const Vector<String16>& args);
friend class AudioStreamOutALSA;
friend class AudioStreamInALSA;
ALSAMixer *mMixer;
AudioStreamOutALSA *mOutput;
AudioStreamInALSA *mInput;
private:
Mutex mLock;
void *mSecRilLibHandle;
HRilClient mRilClient;
bool mVrModeEnabled;
bool mActivatedCP;
bool mBluetoothECOff;
HRilClient (*openClientRILD) (void);
int (*disconnectRILD) (HRilClient);
int (*closeClientRILD) (HRilClient);
int (*isConnectedRILD) (HRilClient);
int (*connectRILD) (HRilClient);
int (*setCallVolume) (HRilClient, SoundType, int);
int (*setCallAudioPath)(HRilClient, AudioPath);
int (*setCallClockSync)(HRilClient, SoundClockCondition);
void loadRILD(void);
status_t connectRILDIfRequired(void);
void setBluetoothNrEcOnOff(bool disable);
};
class ALSADownsampler {
public:
ALSADownsampler(uint32_t outSampleRate,
uint32_t channelCount,
uint32_t frameCount,
ALSABufferProvider* provider);
virtual ~ALSADownsampler();
void reset();
status_t initCheck() { return mStatus; }
int resample(int16_t* out, size_t *outFrameCount);
private:
status_t mStatus;
ALSABufferProvider* mProvider;
uint32_t mSampleRate;
uint32_t mChannelCount;
uint32_t mFrameCount;
int16_t *mInLeft;
int16_t *mInRight;
int16_t *mTmpLeft;
int16_t *mTmpRight;
int16_t *mTmp2Left;
int16_t *mTmp2Right;
int16_t *mOutLeft;
int16_t *mOutRight;
int mInInBuf;
int mInTmpBuf;
int mInTmp2Buf;
int mOutBufPos;
int mInOutBuf;
};
}; // namespace android
#endif // ANDROID_AUDIO_HARDWARE_ALSA_H