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