OSDN Git Service

Support no ALSA mixing.
[android-x86/hardware-alsa_sound.git] / alsa_default.cpp
1 /* alsa_default.cpp
2  **
3  ** Copyright 2009 Wind River Systems
4  **
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
8  **
9  **     http://www.apache.org/licenses/LICENSE-2.0
10  **
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.
16  */
17
18 #define LOG_TAG "ALSAModule"
19 #include <utils/Log.h>
20
21 #include "AudioHardwareALSA.h"
22 #include <media/AudioRecord.h>
23
24 #undef DISABLE_HARWARE_RESAMPLING
25
26 #define ALSA_NAME_MAX 128
27
28 #define ALSA_STRCAT(x,y) \
29     if (strlen(x) + strlen(y) < ALSA_NAME_MAX) \
30         strcat(x, y);
31
32 #ifndef ALSA_DEFAULT_SAMPLE_RATE
33 #define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
34 #endif
35
36 namespace android
37 {
38
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);
45
46 static hw_module_methods_t s_module_methods = {
47     open            : s_device_open
48 };
49
50 extern "C" const hw_module_t HAL_MODULE_INFO_SYM = {
51     tag             : HARDWARE_MODULE_TAG,
52     version_major   : 1,
53     version_minor   : 0,
54     id              : ALSA_HARDWARE_MODULE_ID,
55     name            : "ALSA module",
56     author          : "Wind River",
57     methods         : &s_module_methods,
58     dso             : 0,
59     reserved        : { 0, },
60 };
61
62 static int s_device_open(const hw_module_t* module, const char* name,
63         hw_device_t** device)
64 {
65     alsa_device_t *dev;
66     dev = (alsa_device_t *) malloc(sizeof(*dev));
67     if (!dev) return -ENOMEM;
68
69     memset(dev, 0, sizeof(*dev));
70
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;
76     dev->init = s_init;
77     dev->open = s_open;
78     dev->close = s_close;
79     dev->route = s_route;
80
81     *device = &dev->common;
82     return 0;
83 }
84
85 static int s_device_close(hw_device_t* device)
86 {
87     free(device);
88     return 0;
89 }
90
91 // ----------------------------------------------------------------------------
92
93 static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
94
95 static const char *devicePrefix[SND_PCM_STREAM_LAST + 1] = {
96         /* SND_PCM_STREAM_PLAYBACK : */"AndroidPlayback",
97         /* SND_PCM_STREAM_CAPTURE  : */"AndroidCapture",
98 };
99
100 static alsa_handle_t _defaultsOut = {
101     module      : 0,
102     devices     : AudioSystem::DEVICE_OUT_ALL,
103     curDev      : 0,
104     curMode     : 0,
105     handle      : 0,
106     format      : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
107     channels    : 2,
108     sampleRate  : DEFAULT_SAMPLE_RATE,
109     latency     : 200000, // Desired Delay in usec
110     bufferSize  : DEFAULT_SAMPLE_RATE / 5, // Desired Number of samples
111     modPrivate  : 0,
112 };
113
114 static alsa_handle_t _defaultsIn = {
115     module      : 0,
116     devices     : AudioSystem::DEVICE_IN_ALL,
117     curDev      : 0,
118     curMode     : 0,
119     handle      : 0,
120     format      : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
121     channels    : 1,
122     sampleRate  : AudioRecord::DEFAULT_SAMPLE_RATE,
123     latency     : 250000, // Desired Delay in usec
124     bufferSize  : 2048, // Desired Number of samples
125     modPrivate  : 0,
126 };
127
128 struct device_suffix_t {
129     const AudioSystem::audio_devices device;
130     const char *suffix;
131 };
132
133 /* The following table(s) need to match in order of the route bits
134  */
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"},
141 };
142
143 static const int deviceSuffixLen = (sizeof(deviceSuffix)
144         / sizeof(device_suffix_t));
145
146 // ----------------------------------------------------------------------------
147
148 snd_pcm_stream_t direction(alsa_handle_t *handle)
149 {
150     return (handle->devices & AudioSystem::DEVICE_OUT_ALL) ? SND_PCM_STREAM_PLAYBACK
151             : SND_PCM_STREAM_CAPTURE;
152 }
153
154 const char *deviceName(alsa_handle_t *handle, uint32_t device, int mode)
155 {
156     static char devString[ALSA_NAME_MAX];
157     int hasDevExt = 0;
158
159     strcpy(devString, devicePrefix[direction(handle)]);
160
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;
165             hasDevExt = 1;
166         }
167
168     if (hasDevExt) switch (mode) {
169     case AudioSystem::MODE_NORMAL:
170         ALSA_STRCAT (devString, "_normal")
171         ;
172         break;
173     case AudioSystem::MODE_RINGTONE:
174         ALSA_STRCAT (devString, "_ringtone")
175         ;
176         break;
177     case AudioSystem::MODE_IN_CALL:
178         ALSA_STRCAT (devString, "_incall")
179         ;
180         break;
181     };
182
183     return devString;
184 }
185
186 const char *streamName(alsa_handle_t *handle)
187 {
188     return snd_pcm_stream_name(direction(handle));
189 }
190
191 status_t setHardwareParams(alsa_handle_t *handle)
192 {
193     snd_pcm_hw_params_t *hardwareParams;
194     status_t err;
195
196     snd_pcm_uframes_t bufferSize = handle->bufferSize;
197     unsigned int requestedRate = handle->sampleRate;
198     unsigned int latency = handle->latency;
199
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)
208             : "UNKNOWN";
209
210     if (snd_pcm_hw_params_malloc(&hardwareParams) < 0) {
211         LOG_ALWAYS_FATAL("Failed to allocate ALSA hardware parameters!");
212         return NO_INIT;
213     }
214
215     err = snd_pcm_hw_params_any(handle->handle, hardwareParams);
216     if (err < 0) {
217         LOGE("Unable to configure hardware: %s", snd_strerror(err));
218         goto done;
219     }
220
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);
224     if (err < 0) {
225         LOGE("Unable to configure PCM read/write format: %s",
226                 snd_strerror(err));
227         goto done;
228     }
229
230     err = snd_pcm_hw_params_set_format(handle->handle, hardwareParams,
231             handle->format);
232     if (err < 0) {
233         LOGE("Unable to configure PCM format %s (%s): %s",
234                 formatName, formatDesc, snd_strerror(err));
235         goto done;
236     }
237
238     LOGV("Set %s PCM format to %s (%s)", streamName(), formatName, formatDesc);
239
240     err = snd_pcm_hw_params_set_channels(handle->handle, hardwareParams,
241             handle->channels);
242     if (err < 0) {
243         LOGE("Unable to set channel count to %i: %s",
244                 handle->channels, snd_strerror(err));
245         goto done;
246     }
247
248     LOGV("Using %i %s for %s.", handle->channels,
249             handle->channels == 1 ? "channel" : "channels", streamName());
250
251     err = snd_pcm_hw_params_set_rate_near(handle->handle, hardwareParams,
252             &requestedRate, 0);
253
254     if (err < 0)
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
260         // slow or fast.
261         LOGW("Requested rate (%u HZ) does not match actual rate (%u HZ)",
262                 handle->sampleRate, requestedRate);
263     else
264         LOGV("Set %s sample rate to %u HZ", stream, requestedRate);
265
266 #ifdef DISABLE_HARWARE_RESAMPLING
267     // Disable hardware re-sampling.
268     err = snd_pcm_hw_params_set_rate_resample(handle->handle,
269             hardwareParams,
270             static_cast<int>(resample));
271     if (err < 0) {
272         LOGE("Unable to %s hardware resampling: %s",
273                 resample ? "enable" : "disable",
274                 snd_strerror(err));
275         goto done;
276     }
277 #endif
278
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,
281             &bufferSize);
282
283     if (err < 0) {
284         LOGE("Unable to set buffer size to %d:  %s",
285                 (int)bufferSize, snd_strerror(err));
286         goto done;
287     }
288
289     // Setup buffers for latency
290     err = snd_pcm_hw_params_set_buffer_time_near(handle->handle,
291             hardwareParams, &latency, NULL);
292     if (err < 0) {
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);
297         if (err < 0) {
298             LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
299             goto done;
300         }
301         snd_pcm_uframes_t periodSize;
302         err = snd_pcm_hw_params_get_period_size(hardwareParams, &periodSize,
303                 NULL);
304         if (err < 0) {
305             LOGE("Unable to get the period size for latency: %s", snd_strerror(err));
306             goto done;
307         }
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);
312         if (err < 0) {
313             LOGE("Unable to set the buffer size for latency: %s", snd_strerror(err));
314             goto done;
315         }
316     } else {
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);
319         if (err < 0) {
320             LOGE("Unable to get the buffer size for latency: %s", snd_strerror(err));
321             goto done;
322         }
323         // Does set_buffer_time_near change the passed value? It should.
324         err = snd_pcm_hw_params_get_buffer_time(hardwareParams, &latency, NULL);
325         if (err < 0) {
326             LOGE("Unable to get the buffer time for latency: %s", snd_strerror(err));
327             goto done;
328         }
329         unsigned int periodTime = latency / 4;
330         err = snd_pcm_hw_params_set_period_time_near(handle->handle,
331                 hardwareParams, &periodTime, NULL);
332         if (err < 0) {
333             LOGE("Unable to set the period time for latency: %s", snd_strerror(err));
334             goto done;
335         }
336     }
337
338     LOGV("Buffer size: %d", (int)bufferSize);
339     LOGV("Latency: %d", (int)latency);
340
341     handle->bufferSize = bufferSize;
342     handle->latency = latency;
343
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));
347
348     done:
349     snd_pcm_hw_params_free(hardwareParams);
350
351     return err;
352 }
353
354 status_t setSoftwareParams(alsa_handle_t *handle)
355 {
356     snd_pcm_sw_params_t * softwareParams;
357     int err;
358
359     snd_pcm_uframes_t bufferSize = 0;
360     snd_pcm_uframes_t periodSize = 0;
361     snd_pcm_uframes_t startThreshold, stopThreshold;
362
363     if (snd_pcm_sw_params_malloc(&softwareParams) < 0) {
364         LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
365         return NO_INIT;
366     }
367
368     // Get the current software parameters
369     err = snd_pcm_sw_params_current(handle->handle, softwareParams);
370     if (err < 0) {
371         LOGE("Unable to get software parameters: %s", snd_strerror(err));
372         goto done;
373     }
374
375     // Configure ALSA to start the transfer when the buffer is almost full.
376     snd_pcm_get_params(handle->handle, &bufferSize, &periodSize);
377
378     if (handle->devices & AudioSystem::DEVICE_OUT_ALL) {
379         // For playback, configure ALSA to start the transfer when the
380         // buffer is full.
381         startThreshold = bufferSize - 1;
382         stopThreshold = bufferSize;
383     } else {
384         // For recording, configure ALSA to start the transfer on the
385         // first frame.
386         startThreshold = 1;
387         stopThreshold = bufferSize;
388     }
389
390     err = snd_pcm_sw_params_set_start_threshold(handle->handle, softwareParams,
391             startThreshold);
392     if (err < 0) {
393         LOGE("Unable to set start threshold to %lu frames: %s",
394                 startThreshold, snd_strerror(err));
395         goto done;
396     }
397
398     err = snd_pcm_sw_params_set_stop_threshold(handle->handle, softwareParams,
399             stopThreshold);
400     if (err < 0) {
401         LOGE("Unable to set stop threshold to %lu frames: %s",
402                 stopThreshold, snd_strerror(err));
403         goto done;
404     }
405
406     // Allow the transfer to start when at least periodSize samples can be
407     // processed.
408     err = snd_pcm_sw_params_set_avail_min(handle->handle, softwareParams,
409             periodSize);
410     if (err < 0) {
411         LOGE("Unable to configure available minimum to %lu: %s",
412                 periodSize, snd_strerror(err));
413         goto done;
414     }
415
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",
419             snd_strerror(err));
420
421     done:
422     snd_pcm_sw_params_free(softwareParams);
423
424     return err;
425 }
426
427 // ----------------------------------------------------------------------------
428
429 static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
430 {
431     list.clear();
432
433     snd_pcm_uframes_t bufferSize = _defaultsOut.bufferSize;
434
435     for (size_t i = 1; (bufferSize & ~i) != 0; i <<= 1)
436         bufferSize &= ~i;
437
438     _defaultsOut.module = module;
439     _defaultsOut.bufferSize = bufferSize;
440
441     list.push_back(_defaultsOut);
442
443     bufferSize = _defaultsIn.bufferSize;
444
445     for (size_t i = 1; (bufferSize & ~i) != 0; i <<= 1)
446         bufferSize &= ~i;
447
448     _defaultsIn.module = module;
449     _defaultsIn.bufferSize = bufferSize;
450
451     list.push_back(_defaultsIn);
452
453     return NO_ERROR;
454 }
455
456 static status_t s_open(alsa_handle_t *handle, uint32_t devices, int mode)
457 {
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).
462     //
463     s_close(handle);
464
465     LOGD("open called for devices %08x in mode %d...", devices, mode);
466
467     const char *stream = streamName(handle);
468     const char *devName = deviceName(handle, devices, mode);
469
470     int err;
471
472     for (;;) {
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),
477                 SND_PCM_ASYNC);
478         if (err == 0) break;
479
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, '_');
483         if (!tail) break;
484         *tail = 0;
485     }
486
487     if (err < 0) {
488         // None of the Android defined audio devices exist. Open a generic one.
489         devName = "default";
490         err = snd_pcm_open(&handle->handle, devName, direction(handle), 0);
491     }
492
493     if (err < 0) {
494         LOGE("Failed to Initialize any ALSA %s device: %s",
495                 stream, strerror(err));
496         return NO_INIT;
497     }
498
499     err = setHardwareParams(handle);
500
501     if (err == NO_ERROR) err = setSoftwareParams(handle);
502
503     LOGI("Initialized ALSA %s device %s", stream, devName);
504
505     handle->curDev = devices;
506     handle->curMode = mode;
507
508     return err;
509 }
510
511 static status_t s_close(alsa_handle_t *handle)
512 {
513     status_t err = NO_ERROR;
514     snd_pcm_t *h = handle->handle;
515     handle->handle = 0;
516     handle->curDev = 0;
517     handle->curMode = 0;
518     if (h) {
519         snd_pcm_drain(h);
520         err = snd_pcm_close(h);
521     }
522
523     return err;
524 }
525
526 static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
527 {
528     LOGD("route called for devices %08x in mode %d...", devices, mode);
529
530     if (handle->handle && handle->curDev == devices && handle->curMode == mode) return NO_ERROR;
531
532     return s_open(handle, devices, mode);
533 }
534
535 }