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