3 ** Copyright 2009 Wind River Systems
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
18 #define LOG_TAG "ALSAModule"
19 #include <utils/Log.h>
21 #include "AudioHardwareALSA.h"
22 #include <media/AudioRecord.h>
24 #undef DISABLE_HARWARE_RESAMPLING
26 #define ALSA_NAME_MAX 128
28 #define ALSA_STRCAT(x,y) \
29 if (strlen(x) + strlen(y) < ALSA_NAME_MAX) \
32 #ifndef ALSA_DEFAULT_SAMPLE_RATE
33 #define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
39 static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
40 static int s_device_close(hw_device_t*);
41 static status_t s_init(alsa_device_t *, ALSAHandleList &);
42 static status_t s_open(alsa_handle_t *, uint32_t, int);
43 static status_t s_close(alsa_handle_t *);
44 static status_t s_route(alsa_handle_t *, uint32_t, int);
46 static hw_module_methods_t s_module_methods = {
50 extern "C" const hw_module_t HAL_MODULE_INFO_SYM = {
51 tag : HARDWARE_MODULE_TAG,
54 id : ALSA_HARDWARE_MODULE_ID,
56 author : "Wind River",
57 methods : &s_module_methods,
62 static int s_device_open(const hw_module_t* module, const char* name,
66 dev = (alsa_device_t *) malloc(sizeof(*dev));
67 if (!dev) return -ENOMEM;
69 memset(dev, 0, sizeof(*dev));
71 /* initialize the procs */
72 dev->common.tag = HARDWARE_DEVICE_TAG;
73 dev->common.version = 0;
74 dev->common.module = (hw_module_t *) module;
75 dev->common.close = s_device_close;
81 *device = &dev->common;
85 static int s_device_close(hw_device_t* device)
91 // ----------------------------------------------------------------------------
93 static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
95 static const char *devicePrefix[SND_PCM_STREAM_LAST + 1] = {
96 /* SND_PCM_STREAM_PLAYBACK : */"AndroidPlayback",
97 /* SND_PCM_STREAM_CAPTURE : */"AndroidCapture",
100 static alsa_handle_t _defaultsOut = {
102 devices : AudioSystem::DEVICE_OUT_ALL,
106 format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
108 sampleRate : DEFAULT_SAMPLE_RATE,
109 latency : 200000, // Desired Delay in usec
110 bufferSize : DEFAULT_SAMPLE_RATE / 5, // Desired Number of samples
114 static alsa_handle_t _defaultsIn = {
116 devices : AudioSystem::DEVICE_IN_ALL,
120 format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
122 sampleRate : AudioRecord::DEFAULT_SAMPLE_RATE,
123 latency : 250000, // Desired Delay in usec
124 bufferSize : 2048, // Desired Number of samples
128 struct device_suffix_t {
129 const AudioSystem::audio_devices device;
133 /* The following table(s) need to match in order of the route bits
135 static const device_suffix_t deviceSuffix[] = {
136 {AudioSystem::DEVICE_OUT_EARPIECE, "_Earpiece"},
137 {AudioSystem::DEVICE_OUT_SPEAKER, "_Speaker"},
138 {AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, "_Bluetooth"},
139 {AudioSystem::DEVICE_OUT_WIRED_HEADSET, "_Headset"},
140 {AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, "_Bluetooth-A2DP"},
143 static const int deviceSuffixLen = (sizeof(deviceSuffix)
144 / sizeof(device_suffix_t));
146 // ----------------------------------------------------------------------------
148 snd_pcm_stream_t direction(alsa_handle_t *handle)
150 return (handle->devices & AudioSystem::DEVICE_OUT_ALL) ? SND_PCM_STREAM_PLAYBACK
151 : SND_PCM_STREAM_CAPTURE;
154 const char *deviceName(alsa_handle_t *handle, uint32_t device, int mode)
156 static char devString[ALSA_NAME_MAX];
159 strcpy(devString, devicePrefix[direction(handle)]);
161 for (int dev = 0; device && dev < deviceSuffixLen; dev++)
162 if (device & deviceSuffix[dev].device) {
163 ALSA_STRCAT (devString, deviceSuffix[dev].suffix);
164 device &= ~deviceSuffix[dev].device;
168 if (hasDevExt) switch (mode) {
169 case AudioSystem::MODE_NORMAL:
170 ALSA_STRCAT (devString, "_normal")
173 case AudioSystem::MODE_RINGTONE:
174 ALSA_STRCAT (devString, "_ringtone")
177 case AudioSystem::MODE_IN_CALL:
178 ALSA_STRCAT (devString, "_incall")
186 const char *streamName(alsa_handle_t *handle)
188 return snd_pcm_stream_name(direction(handle));
191 status_t setHardwareParams(alsa_handle_t *handle)
193 snd_pcm_hw_params_t *hardwareParams;
196 snd_pcm_uframes_t bufferSize = handle->bufferSize;
197 unsigned int requestedRate = handle->sampleRate;
198 unsigned int latency = handle->latency;
200 // snd_pcm_format_description() and snd_pcm_format_name() do not perform
201 // proper bounds checking.
202 bool validFormat = (static_cast<int> (handle->format)
203 > SND_PCM_FORMAT_UNKNOWN) && (static_cast<int> (handle->format)
204 <= SND_PCM_FORMAT_LAST);
205 const char *formatDesc = validFormat ? snd_pcm_format_description(
206 handle->format) : "Invalid Format";
207 const char *formatName = validFormat ? snd_pcm_format_name(handle->format)
210 if (snd_pcm_hw_params_malloc(&hardwareParams) < 0) {
211 LOG_ALWAYS_FATAL("Failed to allocate ALSA hardware parameters!");
215 err = snd_pcm_hw_params_any(handle->handle, hardwareParams);
217 LOGE("Unable to configure hardware: %s", snd_strerror(err));
221 // Set the interleaved read and write format.
222 err = snd_pcm_hw_params_set_access(handle->handle, hardwareParams,
223 SND_PCM_ACCESS_RW_INTERLEAVED);
225 LOGE("Unable to configure PCM read/write format: %s",
230 err = snd_pcm_hw_params_set_format(handle->handle, hardwareParams,
233 LOGE("Unable to configure PCM format %s (%s): %s",
234 formatName, formatDesc, snd_strerror(err));
238 LOGV("Set %s PCM format to %s (%s)", streamName(), formatName, formatDesc);
240 err = snd_pcm_hw_params_set_channels(handle->handle, hardwareParams,
243 LOGE("Unable to set channel count to %i: %s",
244 handle->channels, snd_strerror(err));
248 LOGV("Using %i %s for %s.", handle->channels,
249 handle->channels == 1 ? "channel" : "channels", streamName());
251 err = snd_pcm_hw_params_set_rate_near(handle->handle, hardwareParams,
255 LOGE("Unable to set %s sample rate to %u: %s",
256 streamName(handle), handle->sampleRate, snd_strerror(err));
257 else if (requestedRate != handle->sampleRate)
258 // Some devices have a fixed sample rate, and can not be changed.
259 // This may cause resampling problems; i.e. PCM playback will be too
261 LOGW("Requested rate (%u HZ) does not match actual rate (%u HZ)",
262 handle->sampleRate, requestedRate);
264 LOGV("Set %s sample rate to %u HZ", stream, requestedRate);
266 #ifdef DISABLE_HARWARE_RESAMPLING
267 // Disable hardware re-sampling.
268 err = snd_pcm_hw_params_set_rate_resample(handle->handle,
270 static_cast<int>(resample));
272 LOGE("Unable to %s hardware resampling: %s",
273 resample ? "enable" : "disable",
279 // Make sure we have at least the size we originally wanted
280 err = snd_pcm_hw_params_set_buffer_size_near(handle->handle, hardwareParams,
284 LOGE("Unable to set buffer size to %d: %s",
285 (int)bufferSize, snd_strerror(err));
289 // Setup buffers for latency
290 err = snd_pcm_hw_params_set_buffer_time_near(handle->handle,
291 hardwareParams, &latency, NULL);
293 /* That didn't work, set the period instead */
294 unsigned int periodTime = latency / 4;
295 err = snd_pcm_hw_params_set_period_time_near(handle->handle,
296 hardwareParams, &periodTime, NULL);
298 LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
301 snd_pcm_uframes_t periodSize;
302 err = snd_pcm_hw_params_get_period_size(hardwareParams, &periodSize,
305 LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
308 bufferSize = periodSize * 4;
309 if (bufferSize < handle->bufferSize) bufferSize = handle->bufferSize;
310 err = snd_pcm_hw_params_set_buffer_size_near(handle->handle,
311 hardwareParams, &bufferSize);
313 LOGE("Unable to set the buffer size for latency: %s", snd_strerror(err));
317 // OK, we got buffer time near what we expect. See what that did for bufferSize.
318 err = snd_pcm_hw_params_get_buffer_size(hardwareParams, &bufferSize);
320 LOGE("Unable to get the buffer size for latency: %s", snd_strerror(err));
323 // Does set_buffer_time_near change the passed value? It should.
324 err = snd_pcm_hw_params_get_buffer_time(hardwareParams, &latency, NULL);
326 LOGE("Unable to get the buffer time for latency: %s", snd_strerror(err));
329 unsigned int periodTime = latency / 4;
330 err = snd_pcm_hw_params_set_period_time_near(handle->handle,
331 hardwareParams, &periodTime, NULL);
333 LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
338 LOGV("Buffer size: %d", (int)bufferSize);
339 LOGV("Latency: %d", (int)latency);
341 handle->bufferSize = bufferSize;
342 handle->latency = latency;
344 // Commit the hardware parameters back to the device.
345 err = snd_pcm_hw_params(handle->handle, hardwareParams);
346 if (err < 0) LOGE("Unable to set hardware parameters: %s", snd_strerror(err));
349 snd_pcm_hw_params_free(hardwareParams);
354 status_t setSoftwareParams(alsa_handle_t *handle)
356 snd_pcm_sw_params_t * softwareParams;
359 snd_pcm_uframes_t bufferSize = 0;
360 snd_pcm_uframes_t periodSize = 0;
361 snd_pcm_uframes_t startThreshold, stopThreshold;
363 if (snd_pcm_sw_params_malloc(&softwareParams) < 0) {
364 LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
368 // Get the current software parameters
369 err = snd_pcm_sw_params_current(handle->handle, softwareParams);
371 LOGE("Unable to get software parameters: %s", snd_strerror(err));
375 // Configure ALSA to start the transfer when the buffer is almost full.
376 snd_pcm_get_params(handle->handle, &bufferSize, &periodSize);
378 if (handle->devices & AudioSystem::DEVICE_OUT_ALL) {
379 // For playback, configure ALSA to start the transfer when the
381 startThreshold = bufferSize - 1;
382 stopThreshold = bufferSize;
384 // For recording, configure ALSA to start the transfer on the
387 stopThreshold = bufferSize;
390 err = snd_pcm_sw_params_set_start_threshold(handle->handle, softwareParams,
393 LOGE("Unable to set start threshold to %lu frames: %s",
394 startThreshold, snd_strerror(err));
398 err = snd_pcm_sw_params_set_stop_threshold(handle->handle, softwareParams,
401 LOGE("Unable to set stop threshold to %lu frames: %s",
402 stopThreshold, snd_strerror(err));
406 // Allow the transfer to start when at least periodSize samples can be
408 err = snd_pcm_sw_params_set_avail_min(handle->handle, softwareParams,
411 LOGE("Unable to configure available minimum to %lu: %s",
412 periodSize, snd_strerror(err));
416 // Commit the software parameters back to the device.
417 err = snd_pcm_sw_params(handle->handle, softwareParams);
418 if (err < 0) LOGE("Unable to configure software parameters: %s",
422 snd_pcm_sw_params_free(softwareParams);
427 // ----------------------------------------------------------------------------
429 static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
433 snd_pcm_uframes_t bufferSize = _defaultsOut.bufferSize;
435 for (size_t i = 1; (bufferSize & ~i) != 0; i <<= 1)
438 _defaultsOut.module = module;
439 _defaultsOut.bufferSize = bufferSize;
441 list.push_back(_defaultsOut);
443 bufferSize = _defaultsIn.bufferSize;
445 for (size_t i = 1; (bufferSize & ~i) != 0; i <<= 1)
448 _defaultsIn.module = module;
449 _defaultsIn.bufferSize = bufferSize;
451 list.push_back(_defaultsIn);
456 static status_t s_open(alsa_handle_t *handle, uint32_t devices, int mode)
458 // Close off previously opened device.
459 // It would be nice to determine if the underlying device actually
460 // changes, but we might be recovering from an error or manipulating
461 // mixer settings (see asound.conf).
465 LOGD("open called for devices %08x in mode %d...", devices, mode);
467 const char *stream = streamName(handle);
468 const char *devName = deviceName(handle, devices, mode);
473 // The PCM stream is opened in blocking mode, per ALSA defaults. The
474 // AudioFlinger seems to assume blocking mode too, so asynchronous mode
475 // should not be used.
476 err = snd_pcm_open(&handle->handle, devName, direction(handle),
480 // See if there is a less specific name we can try.
481 // Note: We are changing the contents of a const char * here.
482 char *tail = strrchr(devName, '_');
488 // None of the Android defined audio devices exist. Open a generic one.
490 err = snd_pcm_open(&handle->handle, devName, direction(handle), 0);
494 LOGE("Failed to Initialize any ALSA %s device: %s",
495 stream, strerror(err));
499 err = setHardwareParams(handle);
501 if (err == NO_ERROR) err = setSoftwareParams(handle);
503 LOGI("Initialized ALSA %s device %s", stream, devName);
505 handle->curDev = devices;
506 handle->curMode = mode;
511 static status_t s_close(alsa_handle_t *handle)
513 status_t err = NO_ERROR;
514 snd_pcm_t *h = handle->handle;
520 err = snd_pcm_close(h);
526 static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
528 LOGD("route called for devices %08x in mode %d...", devices, mode);
530 if (handle->handle && handle->curDev == devices && handle->curMode == mode) return NO_ERROR;
532 return s_open(handle, devices, mode);