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