OSDN Git Service

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