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