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 "audio_hw_default"
18//#define LOG_NDEBUG 0
19
20#include <errno.h>
21#include <malloc.h>
22#include <pthread.h>
23#include <stdint.h>
24#include <sys/time.h>
25
26#include <cutils/log.h>
27
28#include <hardware/hardware.h>
29#include <system/audio.h>
30#include <hardware/audio.h>
31
32struct stub_audio_device {
33    struct audio_hw_device device;
34};
35
36struct stub_stream_out {
37    struct audio_stream_out stream;
38};
39
40struct stub_stream_in {
41    struct audio_stream_in stream;
42};
43
44static uint32_t out_get_sample_rate(const struct audio_stream *stream)
45{
46    return 44100;
47}
48
49static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
50{
51    ALOGV("out_set_sample_rate: %d", 0);
52    return -ENOSYS;
53}
54
55static size_t out_get_buffer_size(const struct audio_stream *stream)
56{
57    ALOGV("out_get_buffer_size: %d", 4096);
58    return 4096;
59}
60
61static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
62{
63    ALOGV("out_get_channels");
64    return AUDIO_CHANNEL_OUT_STEREO;
65}
66
67static audio_format_t out_get_format(const struct audio_stream *stream)
68{
69    ALOGV("out_get_format");
70    return AUDIO_FORMAT_PCM_16_BIT;
71}
72
73static int out_set_format(struct audio_stream *stream, audio_format_t format)
74{
75    ALOGV("out_set_format: %d",format);
76    return -ENOSYS;
77}
78
79static int out_standby(struct audio_stream *stream)
80{
81    ALOGV("out_standby");
82
83    return 0;
84}
85
86static int out_dump(const struct audio_stream *stream, int fd)
87{
88    ALOGV("out_dump");
89    return 0;
90}
91
92static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
93{
94    ALOGV("out_set_parameters");
95    return 0;
96}
97
98static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
99{
100    ALOGV("out_get_parameters");
101    return strdup("");
102}
103
104static uint32_t out_get_latency(const struct audio_stream_out *stream)
105{
106    ALOGV("out_get_latency");
107    return 0;
108}
109
110static int out_set_volume(struct audio_stream_out *stream, float left,
111                          float right)
112{
113    ALOGV("out_set_volume: Left:%f Right:%f", left, right);
114    return 0;
115}
116
117static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
118                         size_t bytes)
119{
120    ALOGV("out_write: bytes: %d", bytes);
121    /* XXX: fake timing for audio output */
122    usleep((int64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
123           out_get_sample_rate(&stream->common));
124    return bytes;
125}
126
127static int out_get_render_position(const struct audio_stream_out *stream,
128                                   uint32_t *dsp_frames)
129{
130    *dsp_frames = 0;
131    ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
132    return -EINVAL;
133}
134
135static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
136{
137    ALOGV("out_add_audio_effect: %p", effect);
138    return 0;
139}
140
141static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
142{
143    ALOGV("out_remove_audio_effect: %p", effect);
144    return 0;
145}
146
147static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
148                                        int64_t *timestamp)
149{
150    *timestamp = 0;
151    ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
152    return -EINVAL;
153}
154
155/** audio_stream_in implementation **/
156static uint32_t in_get_sample_rate(const struct audio_stream *stream)
157{
158    ALOGV("in_get_sample_rate");
159    return 8000;
160}
161
162static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
163{
164    ALOGV("in_set_sample_rate: %d", rate);
165    return -ENOSYS;
166}
167
168static size_t in_get_buffer_size(const struct audio_stream *stream)
169{
170    ALOGV("in_get_buffer_size: %d", 320);
171    return 320;
172}
173
174static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
175{
176    ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO);
177    return AUDIO_CHANNEL_IN_MONO;
178}
179
180static audio_format_t in_get_format(const struct audio_stream *stream)
181{
182    return AUDIO_FORMAT_PCM_16_BIT;
183}
184
185static int in_set_format(struct audio_stream *stream, audio_format_t format)
186{
187    return -ENOSYS;
188}
189
190static int in_standby(struct audio_stream *stream)
191{
192    return 0;
193}
194
195static int in_dump(const struct audio_stream *stream, int fd)
196{
197    return 0;
198}
199
200static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
201{
202    return 0;
203}
204
205static char * in_get_parameters(const struct audio_stream *stream,
206                                const char *keys)
207{
208    return strdup("");
209}
210
211static int in_set_gain(struct audio_stream_in *stream, float gain)
212{
213    return 0;
214}
215
216static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
217                       size_t bytes)
218{
219    ALOGV("in_read: bytes %d", bytes);
220    /* XXX: fake timing for audio input */
221    usleep((int64_t)bytes * 1000000 / audio_stream_in_frame_size(stream) /
222           in_get_sample_rate(&stream->common));
223    memset(buffer, 0, bytes);
224    return bytes;
225}
226
227static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
228{
229    return 0;
230}
231
232static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
233{
234    return 0;
235}
236
237static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
238{
239    return 0;
240}
241
242static int adev_open_output_stream(struct audio_hw_device *dev,
243                                   audio_io_handle_t handle,
244                                   audio_devices_t devices,
245                                   audio_output_flags_t flags,
246                                   struct audio_config *config,
247                                   struct audio_stream_out **stream_out,
248                                   const char *address __unused)
249{
250    ALOGV("adev_open_output_stream...");
251
252    struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
253    struct stub_stream_out *out;
254    int ret;
255
256    out = (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
257    if (!out)
258        return -ENOMEM;
259
260    out->stream.common.get_sample_rate = out_get_sample_rate;
261    out->stream.common.set_sample_rate = out_set_sample_rate;
262    out->stream.common.get_buffer_size = out_get_buffer_size;
263    out->stream.common.get_channels = out_get_channels;
264    out->stream.common.get_format = out_get_format;
265    out->stream.common.set_format = out_set_format;
266    out->stream.common.standby = out_standby;
267    out->stream.common.dump = out_dump;
268    out->stream.common.set_parameters = out_set_parameters;
269    out->stream.common.get_parameters = out_get_parameters;
270    out->stream.common.add_audio_effect = out_add_audio_effect;
271    out->stream.common.remove_audio_effect = out_remove_audio_effect;
272    out->stream.get_latency = out_get_latency;
273    out->stream.set_volume = out_set_volume;
274    out->stream.write = out_write;
275    out->stream.get_render_position = out_get_render_position;
276    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
277
278    *stream_out = &out->stream;
279    return 0;
280
281err_open:
282    free(out);
283    *stream_out = NULL;
284    return ret;
285}
286
287static void adev_close_output_stream(struct audio_hw_device *dev,
288                                     struct audio_stream_out *stream)
289{
290    ALOGV("adev_close_output_stream...");
291    free(stream);
292}
293
294static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
295{
296    ALOGV("adev_set_parameters");
297    return -ENOSYS;
298}
299
300static char * adev_get_parameters(const struct audio_hw_device *dev,
301                                  const char *keys)
302{
303    ALOGV("adev_get_parameters");
304    return strdup("");
305}
306
307static int adev_init_check(const struct audio_hw_device *dev)
308{
309    ALOGV("adev_init_check");
310    return 0;
311}
312
313static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
314{
315    ALOGV("adev_set_voice_volume: %f", volume);
316    return -ENOSYS;
317}
318
319static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
320{
321    ALOGV("adev_set_master_volume: %f", volume);
322    return -ENOSYS;
323}
324
325static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
326{
327    ALOGV("adev_get_master_volume: %f", *volume);
328    return -ENOSYS;
329}
330
331static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
332{
333    ALOGV("adev_set_master_mute: %d", muted);
334    return -ENOSYS;
335}
336
337static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
338{
339    ALOGV("adev_get_master_mute: %d", *muted);
340    return -ENOSYS;
341}
342
343static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
344{
345    ALOGV("adev_set_mode: %d", mode);
346    return 0;
347}
348
349static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
350{
351    ALOGV("adev_set_mic_mute: %d",state);
352    return -ENOSYS;
353}
354
355static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
356{
357    ALOGV("adev_get_mic_mute");
358    return -ENOSYS;
359}
360
361static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
362                                         const struct audio_config *config)
363{
364    ALOGV("adev_get_input_buffer_size: %d", 320);
365    return 320;
366}
367
368static int adev_open_input_stream(struct audio_hw_device *dev,
369                                  audio_io_handle_t handle,
370                                  audio_devices_t devices,
371                                  struct audio_config *config,
372                                  struct audio_stream_in **stream_in,
373                                  audio_input_flags_t flags __unused,
374                                  const char *address __unused,
375                                  audio_source_t source __unused)
376{
377    ALOGV("adev_open_input_stream...");
378
379    struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
380    struct stub_stream_in *in;
381    int ret;
382
383    in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
384    if (!in)
385        return -ENOMEM;
386
387    in->stream.common.get_sample_rate = in_get_sample_rate;
388    in->stream.common.set_sample_rate = in_set_sample_rate;
389    in->stream.common.get_buffer_size = in_get_buffer_size;
390    in->stream.common.get_channels = in_get_channels;
391    in->stream.common.get_format = in_get_format;
392    in->stream.common.set_format = in_set_format;
393    in->stream.common.standby = in_standby;
394    in->stream.common.dump = in_dump;
395    in->stream.common.set_parameters = in_set_parameters;
396    in->stream.common.get_parameters = in_get_parameters;
397    in->stream.common.add_audio_effect = in_add_audio_effect;
398    in->stream.common.remove_audio_effect = in_remove_audio_effect;
399    in->stream.set_gain = in_set_gain;
400    in->stream.read = in_read;
401    in->stream.get_input_frames_lost = in_get_input_frames_lost;
402
403    *stream_in = &in->stream;
404    return 0;
405
406err_open:
407    free(in);
408    *stream_in = NULL;
409    return ret;
410}
411
412static void adev_close_input_stream(struct audio_hw_device *dev,
413                                   struct audio_stream_in *in)
414{
415    ALOGV("adev_close_input_stream...");
416    return;
417}
418
419static int adev_dump(const audio_hw_device_t *device, int fd)
420{
421    ALOGV("adev_dump");
422    return 0;
423}
424
425static int adev_close(hw_device_t *device)
426{
427    ALOGV("adev_close");
428    free(device);
429    return 0;
430}
431
432static int adev_open(const hw_module_t* module, const char* name,
433                     hw_device_t** device)
434{
435    ALOGV("adev_open: %s", name);
436
437    struct stub_audio_device *adev;
438    int ret;
439
440    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
441        return -EINVAL;
442
443    adev = calloc(1, sizeof(struct stub_audio_device));
444    if (!adev)
445        return -ENOMEM;
446
447    adev->device.common.tag = HARDWARE_DEVICE_TAG;
448    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
449    adev->device.common.module = (struct hw_module_t *) module;
450    adev->device.common.close = adev_close;
451
452    adev->device.init_check = adev_init_check;
453    adev->device.set_voice_volume = adev_set_voice_volume;
454    adev->device.set_master_volume = adev_set_master_volume;
455    adev->device.get_master_volume = adev_get_master_volume;
456    adev->device.set_master_mute = adev_set_master_mute;
457    adev->device.get_master_mute = adev_get_master_mute;
458    adev->device.set_mode = adev_set_mode;
459    adev->device.set_mic_mute = adev_set_mic_mute;
460    adev->device.get_mic_mute = adev_get_mic_mute;
461    adev->device.set_parameters = adev_set_parameters;
462    adev->device.get_parameters = adev_get_parameters;
463    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
464    adev->device.open_output_stream = adev_open_output_stream;
465    adev->device.close_output_stream = adev_close_output_stream;
466    adev->device.open_input_stream = adev_open_input_stream;
467    adev->device.close_input_stream = adev_close_input_stream;
468    adev->device.dump = adev_dump;
469
470    *device = &adev->device.common;
471
472    return 0;
473}
474
475static struct hw_module_methods_t hal_module_methods = {
476    .open = adev_open,
477};
478
479struct audio_module HAL_MODULE_INFO_SYM = {
480    .common = {
481        .tag = HARDWARE_MODULE_TAG,
482        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
483        .hal_api_version = HARDWARE_HAL_API_VERSION,
484        .id = AUDIO_HARDWARE_MODULE_ID,
485        .name = "Default audio HW HAL",
486        .author = "The Android Open Source Project",
487        .methods = &hal_module_methods,
488    },
489};
490