OSDN Git Service

merge in ics-release history after reset to master
[android-x86/hardware-libhardware_legacy.git] / audio / audio_hw_hal.cpp
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "legacy_audio_hw_hal"
18 //#define LOG_NDEBUG 0
19
20 #include <stdint.h>
21
22 #include <hardware/hardware.h>
23 #include <system/audio.h>
24 #include <hardware/audio.h>
25
26 #include <hardware_legacy/AudioHardwareInterface.h>
27 #include <hardware_legacy/AudioSystemLegacy.h>
28
29 namespace android_audio_legacy {
30
31 extern "C" {
32
33 struct legacy_audio_module {
34     struct audio_module module;
35 };
36
37 struct legacy_audio_device {
38     struct audio_hw_device device;
39
40     struct AudioHardwareInterface *hwif;
41 };
42
43 struct legacy_stream_out {
44     struct audio_stream_out stream;
45
46     AudioStreamOut *legacy_out;
47 };
48
49 struct legacy_stream_in {
50     struct audio_stream_in stream;
51
52     AudioStreamIn *legacy_in;
53 };
54
55 /** audio_stream_out implementation **/
56 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
57 {
58     const struct legacy_stream_out *out =
59         reinterpret_cast<const struct legacy_stream_out *>(stream);
60     return out->legacy_out->sampleRate();
61 }
62
63 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
64 {
65     struct legacy_stream_out *out =
66         reinterpret_cast<struct legacy_stream_out *>(stream);
67
68     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
69     /* TODO: implement this */
70     return 0;
71 }
72
73 static size_t out_get_buffer_size(const struct audio_stream *stream)
74 {
75     const struct legacy_stream_out *out =
76         reinterpret_cast<const struct legacy_stream_out *>(stream);
77     return out->legacy_out->bufferSize();
78 }
79
80 static uint32_t out_get_channels(const struct audio_stream *stream)
81 {
82     const struct legacy_stream_out *out =
83         reinterpret_cast<const struct legacy_stream_out *>(stream);
84     return out->legacy_out->channels();
85 }
86
87 static audio_format_t out_get_format(const struct audio_stream *stream)
88 {
89     const struct legacy_stream_out *out =
90         reinterpret_cast<const struct legacy_stream_out *>(stream);
91     // legacy API, don't change return type
92     return (audio_format_t) out->legacy_out->format();
93 }
94
95 static int out_set_format(struct audio_stream *stream, audio_format_t format)
96 {
97     struct legacy_stream_out *out =
98         reinterpret_cast<struct legacy_stream_out *>(stream);
99     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
100     /* TODO: implement me */
101     return 0;
102 }
103
104 static int out_standby(struct audio_stream *stream)
105 {
106     struct legacy_stream_out *out =
107         reinterpret_cast<struct legacy_stream_out *>(stream);
108     return out->legacy_out->standby();
109 }
110
111 static int out_dump(const struct audio_stream *stream, int fd)
112 {
113     const struct legacy_stream_out *out =
114         reinterpret_cast<const struct legacy_stream_out *>(stream);
115     Vector<String16> args;
116     return out->legacy_out->dump(fd, args);
117 }
118
119 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
120 {
121     struct legacy_stream_out *out =
122         reinterpret_cast<struct legacy_stream_out *>(stream);
123     return out->legacy_out->setParameters(String8(kvpairs));
124 }
125
126 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
127 {
128     const struct legacy_stream_out *out =
129         reinterpret_cast<const struct legacy_stream_out *>(stream);
130     String8 s8;
131     s8 = out->legacy_out->getParameters(String8(keys));
132     return strdup(s8.string());
133 }
134
135 static uint32_t out_get_latency(const struct audio_stream_out *stream)
136 {
137     const struct legacy_stream_out *out =
138         reinterpret_cast<const struct legacy_stream_out *>(stream);
139     return out->legacy_out->latency();
140 }
141
142 static int out_set_volume(struct audio_stream_out *stream, float left,
143                           float right)
144 {
145     struct legacy_stream_out *out =
146         reinterpret_cast<struct legacy_stream_out *>(stream);
147     return out->legacy_out->setVolume(left, right);
148 }
149
150 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
151                          size_t bytes)
152 {
153     struct legacy_stream_out *out =
154         reinterpret_cast<struct legacy_stream_out *>(stream);
155     return out->legacy_out->write(buffer, bytes);
156 }
157
158 static int out_get_render_position(const struct audio_stream_out *stream,
159                                    uint32_t *dsp_frames)
160 {
161     const struct legacy_stream_out *out =
162         reinterpret_cast<const struct legacy_stream_out *>(stream);
163     return out->legacy_out->getRenderPosition(dsp_frames);
164 }
165
166 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
167 {
168     return 0;
169 }
170
171 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
172 {
173     return 0;
174 }
175
176 /** audio_stream_in implementation **/
177 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
178 {
179     const struct legacy_stream_in *in =
180         reinterpret_cast<const struct legacy_stream_in *>(stream);
181     return in->legacy_in->sampleRate();
182 }
183
184 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
185 {
186     struct legacy_stream_in *in =
187         reinterpret_cast<struct legacy_stream_in *>(stream);
188
189     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
190     /* TODO: implement this */
191     return 0;
192 }
193
194 static size_t in_get_buffer_size(const struct audio_stream *stream)
195 {
196     const struct legacy_stream_in *in =
197         reinterpret_cast<const struct legacy_stream_in *>(stream);
198     return in->legacy_in->bufferSize();
199 }
200
201 static uint32_t in_get_channels(const struct audio_stream *stream)
202 {
203     const struct legacy_stream_in *in =
204         reinterpret_cast<const struct legacy_stream_in *>(stream);
205     return in->legacy_in->channels();
206 }
207
208 static audio_format_t in_get_format(const struct audio_stream *stream)
209 {
210     const struct legacy_stream_in *in =
211         reinterpret_cast<const struct legacy_stream_in *>(stream);
212     // legacy API, don't change return type
213     return (audio_format_t) in->legacy_in->format();
214 }
215
216 static int in_set_format(struct audio_stream *stream, audio_format_t format)
217 {
218     struct legacy_stream_in *in =
219         reinterpret_cast<struct legacy_stream_in *>(stream);
220     ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
221     /* TODO: implement me */
222     return 0;
223 }
224
225 static int in_standby(struct audio_stream *stream)
226 {
227     struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream);
228     return in->legacy_in->standby();
229 }
230
231 static int in_dump(const struct audio_stream *stream, int fd)
232 {
233     const struct legacy_stream_in *in =
234         reinterpret_cast<const struct legacy_stream_in *>(stream);
235     Vector<String16> args;
236     return in->legacy_in->dump(fd, args);
237 }
238
239 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
240 {
241     struct legacy_stream_in *in =
242         reinterpret_cast<struct legacy_stream_in *>(stream);
243     return in->legacy_in->setParameters(String8(kvpairs));
244 }
245
246 static char * in_get_parameters(const struct audio_stream *stream,
247                                 const char *keys)
248 {
249     const struct legacy_stream_in *in =
250         reinterpret_cast<const struct legacy_stream_in *>(stream);
251     String8 s8;
252     s8 = in->legacy_in->getParameters(String8(keys));
253     return strdup(s8.string());
254 }
255
256 static int in_set_gain(struct audio_stream_in *stream, float gain)
257 {
258     struct legacy_stream_in *in =
259         reinterpret_cast<struct legacy_stream_in *>(stream);
260     return in->legacy_in->setGain(gain);
261 }
262
263 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
264                        size_t bytes)
265 {
266     struct legacy_stream_in *in =
267         reinterpret_cast<struct legacy_stream_in *>(stream);
268     return in->legacy_in->read(buffer, bytes);
269 }
270
271 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
272 {
273     struct legacy_stream_in *in =
274         reinterpret_cast<struct legacy_stream_in *>(stream);
275     return in->legacy_in->getInputFramesLost();
276 }
277
278 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
279 {
280     const struct legacy_stream_in *in =
281         reinterpret_cast<const struct legacy_stream_in *>(stream);
282     return in->legacy_in->addAudioEffect(effect);
283 }
284
285 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
286 {
287     const struct legacy_stream_in *in =
288         reinterpret_cast<const struct legacy_stream_in *>(stream);
289     return in->legacy_in->removeAudioEffect(effect);
290 }
291
292 /** audio_hw_device implementation **/
293 static inline struct legacy_audio_device * to_ladev(struct audio_hw_device *dev)
294 {
295     return reinterpret_cast<struct legacy_audio_device *>(dev);
296 }
297
298 static inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev)
299 {
300     return reinterpret_cast<const struct legacy_audio_device *>(dev);
301 }
302
303 static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev)
304 {
305     /* XXX: The old AudioHardwareInterface interface is not smart enough to
306      * tell us this, so we'll lie and basically tell AF that we support the
307      * below input/output devices and cross our fingers. To do things properly,
308      * audio hardware interfaces that need advanced features (like this) should
309      * convert to the new HAL interface and not use this wrapper. */
310
311     return (/* OUT */
312             AUDIO_DEVICE_OUT_EARPIECE |
313             AUDIO_DEVICE_OUT_SPEAKER |
314             AUDIO_DEVICE_OUT_WIRED_HEADSET |
315             AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
316             AUDIO_DEVICE_OUT_AUX_DIGITAL |
317             AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
318             AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
319             AUDIO_DEVICE_OUT_ALL_SCO |
320             AUDIO_DEVICE_OUT_DEFAULT |
321             /* IN */
322             AUDIO_DEVICE_IN_COMMUNICATION |
323             AUDIO_DEVICE_IN_AMBIENT |
324             AUDIO_DEVICE_IN_BUILTIN_MIC |
325             AUDIO_DEVICE_IN_WIRED_HEADSET |
326             AUDIO_DEVICE_IN_AUX_DIGITAL |
327             AUDIO_DEVICE_IN_BACK_MIC |
328             AUDIO_DEVICE_IN_ALL_SCO |
329             AUDIO_DEVICE_IN_DEFAULT);
330 }
331
332 static int adev_init_check(const struct audio_hw_device *dev)
333 {
334     const struct legacy_audio_device *ladev = to_cladev(dev);
335
336     return ladev->hwif->initCheck();
337 }
338
339 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
340 {
341     struct legacy_audio_device *ladev = to_ladev(dev);
342     return ladev->hwif->setVoiceVolume(volume);
343 }
344
345 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
346 {
347     struct legacy_audio_device *ladev = to_ladev(dev);
348     return ladev->hwif->setMasterVolume(volume);
349 }
350
351 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
352 {
353     struct legacy_audio_device *ladev = to_ladev(dev);
354     // as this is the legacy API, don't change it to use audio_mode_t instead of int
355     return ladev->hwif->setMode((int) mode);
356 }
357
358 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
359 {
360     struct legacy_audio_device *ladev = to_ladev(dev);
361     return ladev->hwif->setMicMute(state);
362 }
363
364 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
365 {
366     const struct legacy_audio_device *ladev = to_cladev(dev);
367     return ladev->hwif->getMicMute(state);
368 }
369
370 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
371 {
372     struct legacy_audio_device *ladev = to_ladev(dev);
373     return ladev->hwif->setParameters(String8(kvpairs));
374 }
375
376 static char * adev_get_parameters(const struct audio_hw_device *dev,
377                                   const char *keys)
378 {
379     const struct legacy_audio_device *ladev = to_cladev(dev);
380     String8 s8;
381
382     s8 = ladev->hwif->getParameters(String8(keys));
383     return strdup(s8.string());
384 }
385
386 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
387                                          uint32_t sample_rate, audio_format_t format,
388                                          int channel_count)
389 {
390     const struct legacy_audio_device *ladev = to_cladev(dev);
391     return ladev->hwif->getInputBufferSize(sample_rate, (int) format, channel_count);
392 }
393
394 static int adev_open_output_stream(struct audio_hw_device *dev,
395                                    uint32_t devices,
396                                    audio_format_t *format,
397                                    uint32_t *channels,
398                                    uint32_t *sample_rate,
399                                    struct audio_stream_out **stream_out)
400 {
401     struct legacy_audio_device *ladev = to_ladev(dev);
402     status_t status;
403     struct legacy_stream_out *out;
404     int ret;
405
406     out = (struct legacy_stream_out *)calloc(1, sizeof(*out));
407     if (!out)
408         return -ENOMEM;
409
410     out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) format, channels,
411                                                     sample_rate, &status);
412     if (!out->legacy_out) {
413         ret = status;
414         goto err_open;
415     }
416
417     out->stream.common.get_sample_rate = out_get_sample_rate;
418     out->stream.common.set_sample_rate = out_set_sample_rate;
419     out->stream.common.get_buffer_size = out_get_buffer_size;
420     out->stream.common.get_channels = out_get_channels;
421     out->stream.common.get_format = out_get_format;
422     out->stream.common.set_format = out_set_format;
423     out->stream.common.standby = out_standby;
424     out->stream.common.dump = out_dump;
425     out->stream.common.set_parameters = out_set_parameters;
426     out->stream.common.get_parameters = out_get_parameters;
427     out->stream.common.add_audio_effect = out_add_audio_effect;
428     out->stream.common.remove_audio_effect = out_remove_audio_effect;
429     out->stream.get_latency = out_get_latency;
430     out->stream.set_volume = out_set_volume;
431     out->stream.write = out_write;
432     out->stream.get_render_position = out_get_render_position;
433
434     *stream_out = &out->stream;
435     return 0;
436
437 err_open:
438     free(out);
439     *stream_out = NULL;
440     return ret;
441 }
442
443 static void adev_close_output_stream(struct audio_hw_device *dev,
444                                      struct audio_stream_out* stream)
445 {
446     struct legacy_audio_device *ladev = to_ladev(dev);
447     struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream);
448
449     ladev->hwif->closeOutputStream(out->legacy_out);
450     free(out);
451 }
452
453 /** This method creates and opens the audio hardware input stream */
454 static int adev_open_input_stream(struct audio_hw_device *dev,
455                                   uint32_t devices, audio_format_t *format,
456                                   uint32_t *channels, uint32_t *sample_rate,
457                                   audio_in_acoustics_t acoustics,
458                                   struct audio_stream_in **stream_in)
459 {
460     struct legacy_audio_device *ladev = to_ladev(dev);
461     status_t status;
462     struct legacy_stream_in *in;
463     int ret;
464
465     in = (struct legacy_stream_in *)calloc(1, sizeof(*in));
466     if (!in)
467         return -ENOMEM;
468
469     in->legacy_in = ladev->hwif->openInputStream(devices, (int *) format, channels,
470                                     sample_rate, &status,
471                                     (AudioSystem::audio_in_acoustics)acoustics);
472     if (!in->legacy_in) {
473         ret = status;
474         goto err_open;
475     }
476
477     in->stream.common.get_sample_rate = in_get_sample_rate;
478     in->stream.common.set_sample_rate = in_set_sample_rate;
479     in->stream.common.get_buffer_size = in_get_buffer_size;
480     in->stream.common.get_channels = in_get_channels;
481     in->stream.common.get_format = in_get_format;
482     in->stream.common.set_format = in_set_format;
483     in->stream.common.standby = in_standby;
484     in->stream.common.dump = in_dump;
485     in->stream.common.set_parameters = in_set_parameters;
486     in->stream.common.get_parameters = in_get_parameters;
487     in->stream.common.add_audio_effect = in_add_audio_effect;
488     in->stream.common.remove_audio_effect = in_remove_audio_effect;
489     in->stream.set_gain = in_set_gain;
490     in->stream.read = in_read;
491     in->stream.get_input_frames_lost = in_get_input_frames_lost;
492
493     *stream_in = &in->stream;
494     return 0;
495
496 err_open:
497     free(in);
498     *stream_in = NULL;
499     return ret;
500 }
501
502 static void adev_close_input_stream(struct audio_hw_device *dev,
503                                struct audio_stream_in *stream)
504 {
505     struct legacy_audio_device *ladev = to_ladev(dev);
506     struct legacy_stream_in *in =
507         reinterpret_cast<struct legacy_stream_in *>(stream);
508
509     ladev->hwif->closeInputStream(in->legacy_in);
510     free(in);
511 }
512
513 static int adev_dump(const struct audio_hw_device *dev, int fd)
514 {
515     const struct legacy_audio_device *ladev = to_cladev(dev);
516     Vector<String16> args;
517
518     return ladev->hwif->dumpState(fd, args);
519 }
520
521 static int legacy_adev_close(hw_device_t* device)
522 {
523     struct audio_hw_device *hwdev =
524                         reinterpret_cast<struct audio_hw_device *>(device);
525     struct legacy_audio_device *ladev = to_ladev(hwdev);
526
527     if (!ladev)
528         return 0;
529
530     if (ladev->hwif)
531         delete ladev->hwif;
532
533     free(ladev);
534     return 0;
535 }
536
537 static int legacy_adev_open(const hw_module_t* module, const char* name,
538                             hw_device_t** device)
539 {
540     struct legacy_audio_device *ladev;
541     int ret;
542
543     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
544         return -EINVAL;
545
546     ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev));
547     if (!ladev)
548         return -ENOMEM;
549
550     ladev->device.common.tag = HARDWARE_DEVICE_TAG;
551     ladev->device.common.version = 0;
552     ladev->device.common.module = const_cast<hw_module_t*>(module);
553     ladev->device.common.close = legacy_adev_close;
554
555     ladev->device.get_supported_devices = adev_get_supported_devices;
556     ladev->device.init_check = adev_init_check;
557     ladev->device.set_voice_volume = adev_set_voice_volume;
558     ladev->device.set_master_volume = adev_set_master_volume;
559     ladev->device.set_mode = adev_set_mode;
560     ladev->device.set_mic_mute = adev_set_mic_mute;
561     ladev->device.get_mic_mute = adev_get_mic_mute;
562     ladev->device.set_parameters = adev_set_parameters;
563     ladev->device.get_parameters = adev_get_parameters;
564     ladev->device.get_input_buffer_size = adev_get_input_buffer_size;
565     ladev->device.open_output_stream = adev_open_output_stream;
566     ladev->device.close_output_stream = adev_close_output_stream;
567     ladev->device.open_input_stream = adev_open_input_stream;
568     ladev->device.close_input_stream = adev_close_input_stream;
569     ladev->device.dump = adev_dump;
570
571     ladev->hwif = createAudioHardware();
572     if (!ladev->hwif) {
573         ret = -EIO;
574         goto err_create_audio_hw;
575     }
576
577     *device = &ladev->device.common;
578
579     return 0;
580
581 err_create_audio_hw:
582     free(ladev);
583     return ret;
584 }
585
586 static struct hw_module_methods_t legacy_audio_module_methods = {
587         open: legacy_adev_open
588 };
589
590 struct legacy_audio_module HAL_MODULE_INFO_SYM = {
591     module: {
592         common: {
593             tag: HARDWARE_MODULE_TAG,
594             version_major: 1,
595             version_minor: 0,
596             id: AUDIO_HARDWARE_MODULE_ID,
597             name: "LEGACY Audio HW HAL",
598             author: "The Android Open Source Project",
599             methods: &legacy_audio_module_methods,
600             dso : NULL,
601             reserved : {0},
602         },
603     },
604 };
605
606 }; // extern "C"
607
608 }; // namespace android_audio_legacy