• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #include <pthread.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <cstdint>
21 
22 extern "C"{
23 #include <cutils/str_parms.h>
24 }
25 
26 #include "common/libs/auto_resources/auto_resources.h"
27 #include "common/libs/threads/thunkers.h"
28 #include "guest/hals/audio/audio_hal.h"
29 #include "guest/hals/audio/vsoc_audio.h"
30 #include "guest/hals/audio/vsoc_audio_input_stream.h"
31 #include "guest/libs/platform_support/api_level_fixes.h"
32 
33 namespace cvd {
34 
35 namespace {
36 template <typename F> struct Thunker :
37   ThunkerBase<audio_stream, GceAudioInputStream, F>{};
38 template <typename F> struct InThunker :
39   ThunkerBase<audio_stream_in, GceAudioInputStream, F>{};
40 }
41 
42 #if defined(AUDIO_DEVICE_API_VERSION_3_0)
43 static inline size_t GceAudioFrameSize(const audio_stream_in* s) {
44   return audio_stream_in_frame_size(s);
45 }
46 #elif defined(AUDIO_DEVICE_API_VERSION_2_0)
47 static inline size_t GceAudioFrameSize(const audio_stream_in* s) {
48 
49   return audio_stream_frame_size(&s->common);
50 }
51 #else
52 static inline size_t GceAudioFrameSize(audio_stream_in* s) {
53 
54   return audio_stream_frame_size(&s->common);
55 }
56 #endif
57 
58 GceAudioInputStream::GceAudioInputStream(
59     cvd::GceAudio* dev, audio_devices_t devices, const audio_config& config)
60     : audio_stream_in(),
61       dev_(dev),
62       config_(config),
63       gain_(0.0),
64       device_(devices) {
65   common.get_sample_rate =
66       Thunker<uint32_t()>::call<&GceAudioInputStream::GetSampleRate>;
67   common.set_sample_rate =
68       Thunker<int(uint32_t)>::call<&GceAudioInputStream::SetSampleRate>;
69   common.get_buffer_size =
70       Thunker<size_t()>::call<&GceAudioInputStream::GetBufferSize>;
71   common.get_channels =
72       Thunker<audio_channel_mask_t()>::call<&GceAudioInputStream::GetChannels>;
73   common.get_device =
74       Thunker<audio_devices_t()>::call<&GceAudioInputStream::GetDevice>;
75   common.set_device =
76       Thunker<int(audio_devices_t)>::call<&GceAudioInputStream::SetDevice>;
77   common.get_format =
78       Thunker<audio_format_t()>::call<&GceAudioInputStream::GetFormat>;
79   common.set_format =
80       Thunker<int(audio_format_t)>::call<&GceAudioInputStream::SetFormat>;
81   common.standby =
82       Thunker<int()>::call<&GceAudioInputStream::Standby>;
83   common.dump =
84       Thunker<int(int)>::call<&GceAudioInputStream::Dump>;
85   common.set_parameters = GceAudio::SetStreamParameters;
86   common.get_parameters =
87       Thunker<char*(const char *)>::call<&GceAudioInputStream::GetParameters>;
88   common.add_audio_effect =
89       Thunker<int(effect_handle_t)>::call<&GceAudioInputStream::AddAudioEffect>;
90   common.remove_audio_effect = Thunker<int(effect_handle_t)>::call<
91     &GceAudioInputStream::RemoveAudioEffect>;
92   set_gain = InThunker<int(float)>::call<&GceAudioInputStream::SetGain>;
93   read = InThunker<ssize_t(void*, size_t)>::call<
94     &GceAudioInputStream::Read>;
95   get_input_frames_lost = InThunker<uint32_t()>::call<
96     &GceAudioInputStream::GetInputFramesLost>;
97   frame_size_ = GceAudioFrameSize(this);
98   buffer_model_.reset(
99       new SimulatedInputBuffer(config_.sample_rate, GetBufferSize() /
100                                frame_size_));
101   reported_lost_frames_ = 0;
102 }
103 
104 gce_audio_message GceAudioInputStream::GetStreamDescriptor(
105     uint32_t stream_number, gce_audio_message::message_t event) {
106   gce_audio_message rval;
107   rval.message_type = event;
108   rval.stream_number = stream_number;
109   rval.frame_num = buffer_model_->GetCurrentItemNum();
110   rval.time_presented =
111       buffer_model_->GetLastUpdatedTime().SinceEpoch().GetTS();
112   rval.frame_rate = config_.sample_rate;
113   rval.channel_mask = config_.channel_mask;
114   rval.format = config_.format;
115   rval.frame_size = frame_size_;
116   return rval;
117 }
118 
119 int GceAudioInputStream::Open(GceAudio* dev,
120                               audio_io_handle_t /*handle*/,
121                               audio_devices_t devices,
122                               const audio_config& config,
123                               GceAudioInputStream** stream_in) {
124   D("GceAudioInputStream::%s", __FUNCTION__);
125   *stream_in = new GceAudioInputStream(dev, devices, config);
126   return 0;
127 }
128 
129 int GceAudioInputStream::SetFormat(audio_format_t format) {
130   config_.format = format;
131   frame_size_ = GceAudioFrameSize(this);
132   return 0;
133 }
134 
135 int GceAudioInputStream::Dump(int fd) const {
136   D("GceAudioInputStream::%s", __FUNCTION__);
137   VSOC_FDPRINTF(
138       fd,
139       "\tInputSteam Dump:\n"
140       "\t\tsample rate: %u\n"
141       "\t\tbuffer size: %zu\n"
142       "\t\tchannel mask: %08x\n"
143       "\t\tformat: %d\n"
144       "\t\tdevice: %08x\n"
145       "\t\taudio dev: %p\n\n",
146       GetSampleRate(), GetBufferSize(),
147       GetChannels(), GetFormat(), device_, dev_);
148   return 0;
149 }
150 
151 int GceAudioInputStream::SetSampleRate(uint32_t sample_rate) {
152   if (sample_rate != config_.sample_rate) {
153     config_.sample_rate = sample_rate;
154     buffer_model_.reset(
155         new SimulatedInputBuffer(sample_rate, GetBufferSize() / frame_size_));
156     reported_lost_frames_ = 0;
157   }
158   return 0;
159 }
160 
161 char* GceAudioInputStream::GetParameters(const char* keys) const {
162   D("GceAudioInputStream::%s", __FUNCTION__);
163   if (keys) D("GceAudioInputStream::%s keys %s", __FUNCTION__, keys);
164 
165   str_parms* query = str_parms_create_str(keys);
166   str_parms* reply = str_parms_create();
167 
168   char value[256];
169   int ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING,
170                               value, sizeof(value));
171   char* str;
172   if (ret >= 0) {
173     str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, device_);
174     str = strdup(str_parms_to_str(reply));
175   } else {
176     str = strdup(keys);
177   }
178   str_parms_destroy(query);
179   str_parms_destroy(reply);
180   return str;
181 }
182 
183 
184 ssize_t GceAudioInputStream::Read(void* buffer, size_t bytes) {
185   int64_t available = buffer_model_->RemoveFromInputBuffer(
186       bytes / frame_size_, false) * frame_size_;
187   ssize_t rval = available;
188   if ((rval != available) || (rval < 0)) {
189     ALOGE("GceAudioInputStream:%s got bad value from "
190           "RemoveFromInputBuffer %" PRId64, __FUNCTION__, available);
191     return -1;
192   }
193   memset(buffer, 0, rval);
194   return rval;
195 }
196 
197 }
198