blob: 7bf2453bf2fb60c383c597d59089792328c653bd [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/* AudioHardwareALSA.h
2 **
3 ** Copyright 2008-2010, Wind River Systems
4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
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 ** You may obtain a copy of the License at
9 **
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#ifndef ANDROID_AUDIO_HARDWARE_ALSA_H
20#define ANDROID_AUDIO_HARDWARE_ALSA_H
21
Ajay Dudani92919432012-06-28 14:23:11 -070022#define QCOM_CSDCLIENT_ENABLED 1
23
Iliyan Malchev4765c432012-06-11 14:36:16 -070024#include <utils/List.h>
25#include <hardware_legacy/AudioHardwareBase.h>
26
27#include <hardware_legacy/AudioHardwareInterface.h>
28#include <hardware_legacy/AudioSystemLegacy.h>
29#include <system/audio.h>
30#include <hardware/audio.h>
31#include <utils/threads.h>
Ajay Dudani9746c472012-06-18 16:01:16 -070032#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -070033#include <AudioUsbALSA.h>
Ajay Dudani9746c472012-06-18 16:01:16 -070034#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -070035
36extern "C" {
37 #include <sound/asound.h>
38 #include "alsa_audio.h"
39 #include "msm8960_use_cases.h"
40}
41
42#include <hardware/hardware.h>
43
44namespace android_audio_legacy
45{
46using android::List;
47using android::Mutex;
48class AudioHardwareALSA;
49
50/**
51 * The id of ALSA module
52 */
53#define ALSA_HARDWARE_MODULE_ID "alsa"
54#define ALSA_HARDWARE_NAME "alsa"
55
Glenn Kastena4e23672012-08-28 11:10:40 -070056#define DEFAULT_SAMPLING_RATE 48000
Iliyan Malchev4765c432012-06-11 14:36:16 -070057#define DEFAULT_CHANNEL_MODE 2
58#define VOICE_SAMPLING_RATE 8000
59#define VOICE_CHANNEL_MODE 1
60#define PLAYBACK_LATENCY 96000
61#define RECORD_LATENCY 96000
62#define VOICE_LATENCY 85333
63#define DEFAULT_BUFFER_SIZE 2048
SathishKumar Mani88613382012-08-13 18:40:18 -070064#define PLAYBACK_LOW_LATENCY_BUFFER_SIZE 2048
65#define PLAYBACK_LOW_LATENCY 21500
66#define DEFAULT_IN_BUFFER_SIZE 320
Iliyan Malchev4765c432012-06-11 14:36:16 -070067#define FM_BUFFER_SIZE 1024
68
69#define VOIP_SAMPLING_RATE_8K 8000
70#define VOIP_SAMPLING_RATE_16K 16000
71#define VOIP_DEFAULT_CHANNEL_MODE 1
72#define VOIP_BUFFER_SIZE_8K 320
73#define VOIP_BUFFER_SIZE_16K 640
74#define VOIP_BUFFER_MAX_SIZE VOIP_BUFFER_SIZE_16K
75#define VOIP_PLAYBACK_LATENCY 6400
76#define VOIP_RECORD_LATENCY 6400
77
78#define MODE_IS127 0x2
79#define MODE_4GV_NB 0x3
80#define MODE_4GV_WB 0x4
81#define MODE_AMR 0x5
82#define MODE_AMR_WB 0xD
83#define MODE_PCM 0xC
84
85#define DUALMIC_KEY "dualmic_enabled"
86#define FLUENCE_KEY "fluence"
87#define ANC_KEY "anc_enabled"
88#define TTY_MODE_KEY "tty_mode"
89#define BT_SAMPLERATE_KEY "bt_samplerate"
90#define BTHEADSET_VGS "bt_headset_vgs"
91#define WIDEVOICE_KEY "wide_voice_enable"
92#define VOIPRATE_KEY "voip_rate"
93#define FENS_KEY "fens_enable"
94#define ST_KEY "st_enable"
95#define INCALLMUSIC_KEY "incall_music_enabled"
96
97#define ANC_FLAG 0x00000001
98#define DMIC_FLAG 0x00000002
99#define QMIC_FLAG 0x00000004
Ajay Dudani9746c472012-06-18 16:01:16 -0700100#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700101#define SSRQMIC_FLAG 0x00000008
102#endif
103
104#define TTY_OFF 0x00000010
105#define TTY_FULL 0x00000020
106#define TTY_VCO 0x00000040
107#define TTY_HCO 0x00000080
108#define TTY_CLEAR 0xFFFFFF0F
109
110#define LPA_SESSION_ID 1
111#define TUNNEL_SESSION_ID 2
Ajay Dudani9746c472012-06-18 16:01:16 -0700112#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700113static int USBPLAYBACKBIT_MUSIC = (1 << 0);
114static int USBPLAYBACKBIT_VOICECALL = (1 << 1);
115static int USBPLAYBACKBIT_VOIPCALL = (1 << 2);
116static int USBPLAYBACKBIT_FM = (1 << 3);
117static int USBPLAYBACKBIT_LPA = (1 << 4);
118
119static int USBRECBIT_REC = (1 << 0);
120static int USBRECBIT_VOICECALL = (1 << 1);
121static int USBRECBIT_VOIPCALL = (1 << 2);
122static int USBRECBIT_FM = (1 << 3);
Ajay Dudani9746c472012-06-18 16:01:16 -0700123#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700124
125#define DEVICE_SPEAKER_HEADSET "Speaker Headset"
126#define DEVICE_HEADSET "Headset"
127#define DEVICE_HEADPHONES "Headphones"
128
Ajay Dudani9746c472012-06-18 16:01:16 -0700129#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700130#define COEFF_ARRAY_SIZE 4
131#define FILT_SIZE ((512+1)* 6) /* # ((FFT bins)/2+1)*numOutputs */
132#define SSR_FRAME_SIZE 512
133#define SSR_INPUT_FRAME_SIZE (SSR_FRAME_SIZE * 4)
134#define SSR_OUTPUT_FRAME_SIZE (SSR_FRAME_SIZE * 6)
135#endif
136
137#define MODE_CALL_KEY "CALL_KEY"
138
139struct alsa_device_t;
140static uint32_t FLUENCE_MODE_ENDFIRE = 0;
141static uint32_t FLUENCE_MODE_BROADSIDE = 1;
142
143enum {
144 INCALL_REC_MONO,
145 INCALL_REC_STEREO,
146};
147
Ajay Dudani9746c472012-06-18 16:01:16 -0700148enum audio_call_mode {
149 CS_INACTIVE = 0x0,
150 CS_ACTIVE = 0x1,
151 CS_HOLD = 0x2,
152 IMS_INACTIVE = 0x0,
153 IMS_ACTIVE = 0x10,
154 IMS_HOLD = 0x20
155};
156
157
Iliyan Malchev4765c432012-06-11 14:36:16 -0700158struct alsa_handle_t {
159 alsa_device_t * module;
160 uint32_t devices;
161 char useCase[MAX_STR_LEN];
162 struct pcm * handle;
163 snd_pcm_format_t format;
164 uint32_t channels;
165 uint32_t sampleRate;
166 unsigned int latency; // Delay in usec
167 unsigned int bufferSize; // Size of sample buffer
168 unsigned int periodSize;
SathishKumar Mani88613382012-08-13 18:40:18 -0700169 bool isDeepbufferOutput;
Iliyan Malchev4765c432012-06-11 14:36:16 -0700170 struct pcm * rxHandle;
171 snd_use_case_mgr_t *ucMgr;
172};
173
174typedef List < alsa_handle_t > ALSAHandleList;
175
176struct use_case_t {
177 char useCase[MAX_STR_LEN];
178};
179
180typedef List < use_case_t > ALSAUseCaseList;
181
182struct alsa_device_t {
183 hw_device_t common;
184
185 status_t (*init)(alsa_device_t *, ALSAHandleList &);
186 status_t (*open)(alsa_handle_t *);
187 status_t (*close)(alsa_handle_t *);
188 status_t (*standby)(alsa_handle_t *);
189 status_t (*route)(alsa_handle_t *, uint32_t, int);
190 status_t (*startVoiceCall)(alsa_handle_t *);
191 status_t (*startVoipCall)(alsa_handle_t *);
192 status_t (*startFm)(alsa_handle_t *);
193 void (*setVoiceVolume)(int);
194 void (*setVoipVolume)(int);
195 void (*setMicMute)(int);
196 void (*setVoipMicMute)(int);
197 void (*setVoipConfig)(int, int);
198 status_t (*setFmVolume)(int);
199 void (*setBtscoRate)(int);
200 status_t (*setLpaVolume)(int);
201 void (*enableWideVoice)(bool);
202 void (*enableFENS)(bool);
203 void (*setFlags)(uint32_t);
204 status_t (*setCompressedVolume)(int);
205 void (*enableSlowTalk)(bool);
206 void (*setVocRecMode)(uint8_t);
207 void (*setVoLTEMicMute)(int);
208 void (*setVoLTEVolume)(int);
ty.lee74060de2012-08-02 00:47:00 +0900209#ifdef SEPERATED_AUDIO_INPUT
210 void (*setInput)(int);
211#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700212};
213
214// ----------------------------------------------------------------------------
215
216class ALSAMixer
217{
218public:
219 ALSAMixer();
220 virtual ~ALSAMixer();
221
222 bool isValid() { return 1;}
223 status_t setMasterVolume(float volume);
224 status_t setMasterGain(float gain);
225
226 status_t setVolume(uint32_t device, float left, float right);
227 status_t setGain(uint32_t device, float gain);
228
229 status_t setCaptureMuteState(uint32_t device, bool state);
230 status_t getCaptureMuteState(uint32_t device, bool *state);
231 status_t setPlaybackMuteState(uint32_t device, bool state);
232 status_t getPlaybackMuteState(uint32_t device, bool *state);
233
234};
235
236class ALSAControl
237{
238public:
239 ALSAControl(const char *device = "/dev/snd/controlC0");
240 virtual ~ALSAControl();
241
242 status_t get(const char *name, unsigned int &value, int index = 0);
243 status_t set(const char *name, unsigned int value, int index = -1);
244 status_t set(const char *name, const char *);
245 status_t setext(const char *name, int count, char **setValues);
246
247private:
248 struct mixer* mHandle;
249};
250
251class ALSAStreamOps
252{
253public:
254 ALSAStreamOps(AudioHardwareALSA *parent, alsa_handle_t *handle);
255 virtual ~ALSAStreamOps();
256
257 status_t set(int *format, uint32_t *channels, uint32_t *rate, uint32_t device);
258
259 status_t setParameters(const String8& keyValuePairs);
260 String8 getParameters(const String8& keys);
261
262 uint32_t sampleRate() const;
263 size_t bufferSize() const;
264 int format() const;
265 uint32_t channels() const;
266
267 status_t open(int mode);
268 void close();
269
270protected:
271 friend class AudioHardwareALSA;
272
273 AudioHardwareALSA * mParent;
274 alsa_handle_t * mHandle;
275 uint32_t mDevices;
276};
277
278// ----------------------------------------------------------------------------
279
280class AudioStreamOutALSA : public AudioStreamOut, public ALSAStreamOps
281{
282public:
283 AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle);
284 virtual ~AudioStreamOutALSA();
285
286 virtual uint32_t sampleRate() const
287 {
288 return ALSAStreamOps::sampleRate();
289 }
290
291 virtual size_t bufferSize() const
292 {
293 return ALSAStreamOps::bufferSize();
294 }
295
296 virtual uint32_t channels() const;
297
298 virtual int format() const
299 {
300 return ALSAStreamOps::format();
301 }
302
303 virtual uint32_t latency() const;
304
305 virtual ssize_t write(const void *buffer, size_t bytes);
306 virtual status_t dump(int fd, const Vector<String16>& args);
307
308 status_t setVolume(float left, float right);
309
310 virtual status_t standby();
311
312 virtual status_t setParameters(const String8& keyValuePairs) {
313 return ALSAStreamOps::setParameters(keyValuePairs);
314 }
315
316 virtual String8 getParameters(const String8& keys) {
317 return ALSAStreamOps::getParameters(keys);
318 }
319
320 // return the number of audio frames written by the audio dsp to DAC since
321 // the output has exited standby
322 virtual status_t getRenderPosition(uint32_t *dspFrames);
323
324 status_t open(int mode);
325 status_t close();
326
327private:
328 uint32_t mFrameCount;
329
330protected:
331 AudioHardwareALSA * mParent;
332};
333
334class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps
335{
336public:
337 AudioStreamInALSA(AudioHardwareALSA *parent,
338 alsa_handle_t *handle,
339 AudioSystem::audio_in_acoustics audio_acoustics);
340 virtual ~AudioStreamInALSA();
341
342 virtual uint32_t sampleRate() const
343 {
344 return ALSAStreamOps::sampleRate();
345 }
346
347 virtual size_t bufferSize() const
348 {
349 return ALSAStreamOps::bufferSize();
350 }
351
352 virtual uint32_t channels() const
353 {
354 return ALSAStreamOps::channels();
355 }
356
357 virtual int format() const
358 {
359 return ALSAStreamOps::format();
360 }
361
362 virtual ssize_t read(void* buffer, ssize_t bytes);
363 virtual status_t dump(int fd, const Vector<String16>& args);
364
365 virtual status_t setGain(float gain);
366
367 virtual status_t standby();
368
369 virtual status_t setParameters(const String8& keyValuePairs)
370 {
371 return ALSAStreamOps::setParameters(keyValuePairs);
372 }
373
374 virtual String8 getParameters(const String8& keys)
375 {
376 return ALSAStreamOps::getParameters(keys);
377 }
378
379 // Return the amount of input frames lost in the audio driver since the last call of this function.
380 // Audio driver is expected to reset the value to 0 and restart counting upon returning the current value by this function call.
381 // Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
382 // Unit: the number of input audio frames
383 virtual unsigned int getInputFramesLost() const;
384
385 virtual status_t addAudioEffect(effect_handle_t effect)
386 {
387 return BAD_VALUE;
388 }
389
390 virtual status_t removeAudioEffect(effect_handle_t effect)
391 {
392 return BAD_VALUE;
393 }
394 status_t setAcousticParams(void* params);
395
396 status_t open(int mode);
397 status_t close();
Ajay Dudani9746c472012-06-18 16:01:16 -0700398#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700399 // Helper function to initialize the Surround Sound library.
400 status_t initSurroundSoundLibrary(unsigned long buffersize);
401#endif
402
403private:
404 void resetFramesLost();
405
406 unsigned int mFramesLost;
407 AudioSystem::audio_in_acoustics mAcoustics;
408
Ajay Dudani9746c472012-06-18 16:01:16 -0700409#ifdef QCOM_SSR_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700410 // Function to read coefficients from files.
411 status_t readCoeffsFromFile();
412
413 FILE *mFp_4ch;
414 FILE *mFp_6ch;
415 int16_t **mRealCoeffs;
416 int16_t **mImagCoeffs;
417 void *mSurroundObj;
418
419 int16_t *mSurroundInputBuffer;
420 int16_t *mSurroundOutputBuffer;
421 int mSurroundInputBufferIdx;
422 int mSurroundOutputBufferIdx;
423#endif
424
425protected:
426 AudioHardwareALSA * mParent;
427};
428
429class AudioHardwareALSA : public AudioHardwareBase
430{
431public:
432 AudioHardwareALSA();
433 virtual ~AudioHardwareALSA();
434
435 /**
436 * check to see if the audio hardware interface has been initialized.
437 * return status based on values defined in include/utils/Errors.h
438 */
439 virtual status_t initCheck();
440
441 /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
442 virtual status_t setVoiceVolume(float volume);
443
444 /**
445 * set the audio volume for all audio activities other than voice call.
446 * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
447 * the software mixer will emulate this capability.
448 */
449 virtual status_t setMasterVolume(float volume);
Ajay Dudani9746c472012-06-18 16:01:16 -0700450#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700451 virtual status_t setFmVolume(float volume);
452#endif
453 /**
454 * setMode is called when the audio mode changes. NORMAL mode is for
455 * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
456 * when a call is in progress.
457 */
458 virtual status_t setMode(int mode);
459
460 // mic mute
461 virtual status_t setMicMute(bool state);
462 virtual status_t getMicMute(bool* state);
463
464 // set/get global audio parameters
465 virtual status_t setParameters(const String8& keyValuePairs);
466 virtual String8 getParameters(const String8& keys);
467
468 // Returns audio input buffer size according to parameters passed or 0 if one of the
469 // parameters is not supported
470 virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channels);
471
Ajay Dudani9746c472012-06-18 16:01:16 -0700472#ifdef QCOM_TUNNEL_LPA_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700473 /** This method creates and opens the audio hardware output
474 * session for LPA */
475 virtual AudioStreamOut* openOutputSession(
476 uint32_t devices,
477 int *format,
478 status_t *status,
479 int sessionId,
480 uint32_t samplingRate=0,
481 uint32_t channels=0);
482 virtual void closeOutputSession(AudioStreamOut* out);
Ajay Dudani9746c472012-06-18 16:01:16 -0700483#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700484
485 /** This method creates and opens the audio hardware output stream */
486 virtual AudioStreamOut* openOutputStream(
487 uint32_t devices,
488 int *format=0,
489 uint32_t *channels=0,
490 uint32_t *sampleRate=0,
491 status_t *status=0);
492 virtual void closeOutputStream(AudioStreamOut* out);
493
494 /** This method creates and opens the audio hardware input stream */
495 virtual AudioStreamIn* openInputStream(
496 uint32_t devices,
497 int *format,
498 uint32_t *channels,
499 uint32_t *sampleRate,
500 status_t *status,
501 AudioSystem::audio_in_acoustics acoustics);
502 virtual void closeInputStream(AudioStreamIn* in);
503
504 /**This method dumps the state of the audio hardware */
505 //virtual status_t dumpState(int fd, const Vector<String16>& args);
506
507 static AudioHardwareInterface* create();
508
509 int mode()
510 {
511 return mMode;
512 }
513
514protected:
515 virtual status_t dump(int fd, const Vector<String16>& args);
516 virtual uint32_t getVoipMode(int format);
517 void doRouting(int device);
Ajay Dudani9746c472012-06-18 16:01:16 -0700518#ifdef QCOM_FM_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700519 void handleFm(int device);
520#endif
Ajay Dudani9746c472012-06-18 16:01:16 -0700521#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700522 void closeUSBPlayback();
523 void closeUSBRecording();
524 void closeUsbRecordingIfNothingActive();
525 void closeUsbPlaybackIfNothingActive();
526 void startUsbPlaybackIfNotStarted();
527 void startUsbRecordingIfNotStarted();
Ajay Dudani9746c472012-06-18 16:01:16 -0700528#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700529
530 void disableVoiceCall(char* verb, char* modifier, int mode, int device);
531 void enableVoiceCall(char* verb, char* modifier, int mode, int device);
532 bool routeVoiceCall(int device, int newMode);
533 bool routeVoLTECall(int device, int newMode);
534 friend class AudioStreamOutALSA;
535 friend class AudioStreamInALSA;
536 friend class ALSAStreamOps;
537
538 alsa_device_t * mALSADevice;
539
540 ALSAHandleList mDeviceList;
541
Ajay Dudani9746c472012-06-18 16:01:16 -0700542#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700543 AudioUsbALSA *mAudioUsbALSA;
Ajay Dudani9746c472012-06-18 16:01:16 -0700544#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700545
546 Mutex mLock;
547
548 snd_use_case_mgr_t *mUcMgr;
549
550 uint32_t mCurDevice;
551 /* The flag holds all the audio related device settings from
552 * Settings and Qualcomm Settings applications */
553 uint32_t mDevSettingsFlag;
554 uint32_t mVoipStreamCount;
555 bool mVoipMicMute;
556 uint32_t mVoipBitRate;
557 uint32_t mIncallMode;
558
559 bool mMicMute;
560 int mCSCallActive;
561 int mVolteCallActive;
562 int mCallState;
563 int mIsFmActive;
564 bool mBluetoothVGS;
565 bool mFusion3Platform;
Ajay Dudani9746c472012-06-18 16:01:16 -0700566#ifdef QCOM_USBAUDIO_ENABLED
Iliyan Malchev4765c432012-06-11 14:36:16 -0700567 int musbPlaybackState;
568 int musbRecordingState;
Ajay Dudani9746c472012-06-18 16:01:16 -0700569#endif
Iliyan Malchev4765c432012-06-11 14:36:16 -0700570};
571
572// ----------------------------------------------------------------------------
573
574}; // namespace android_audio_legacy
575#endif // ANDROID_AUDIO_HARDWARE_ALSA_H