Changeset 992ef56 in mainline
- Timestamp:
- 2012-07-12T17:24:51Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1240bb9
- Parents:
- ec49085
- Location:
- uspace/srv/audio/hound
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/audio/hound/Makefile
rec49085 r992ef56 28 28 29 29 USPACE_PREFIX = ../../.. 30 EXTRA_CFLAGS = -DNAME="\"hound\""31 30 BINARY = hound 31 32 EXTRA_CFLAGS = \ 33 -DNAME="\"hound\"" \ 34 -I$(LIBDRV_PREFIX)/include 35 36 LIBS = \ 37 $(LIBDRV_PREFIX)/libdrv.a 32 38 33 39 SOURCES = \ -
uspace/srv/audio/hound/audio_device.c
rec49085 r992ef56 42 42 #include <str_error.h> 43 43 44 #include <audio_pcm_iface.h> 45 44 46 #include "audio_device.h" 45 47 #include "log.h" 46 48 49 #define BUFFER_BLOCKS 2 50 47 51 static int device_sink_connection_callback(void* arg); 48 52 static int device_source_connection_callback(void* arg, const audio_format_t *f); 49 static int audio_device_get_buffer(audio_device_t *dev) 50 { 51 // TODO implement 52 return ENOTSUP; 53 } 54 static int audio_device_release_buffer(audio_device_t *dev) 55 { 56 // TODO implement 57 return ENOTSUP; 58 } 59 static int audio_device_start_playback(audio_device_t *dev) 60 { 61 // TODO implement 62 return ENOTSUP; 63 } 64 static int audio_device_stop_playback(audio_device_t *dev) 65 { 66 // TODO implement 67 return ENOTSUP; 68 } 69 static int audio_device_start_recording(audio_device_t *dev) 70 { 71 // TODO implement 72 return ENOTSUP; 73 } 74 static int audio_device_stop_recording(audio_device_t *dev) 75 { 76 // TODO implement 77 return ENOTSUP; 78 } 53 static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void *arg); 54 static int get_buffer(audio_device_t *dev); 55 static int release_buffer(audio_device_t *dev); 56 static int start_playback(audio_device_t *dev); 57 static int stop_playback(audio_device_t *dev); 58 static int start_recording(audio_device_t *dev); 59 static int stop_recording(audio_device_t *dev); 79 60 80 61 … … 99 80 device_source_connection_callback, dev); 100 81 82 /* Init buffer members */ 83 fibril_mutex_initialize(&dev->buffer.guard); 84 fibril_condvar_initialize(&dev->buffer.wc); 85 dev->buffer.id = 0; 86 dev->buffer.base = NULL; 87 dev->buffer.position = NULL; 88 dev->buffer.size = 0; 89 101 90 log_verbose("Initialized device (%p) '%s' with id %u.", 102 91 dev, dev->name, dev->id); … … 109 98 audio_device_t *dev = arg; 110 99 if (list_count(&dev->sink.sources) == 1) { 111 int ret = audio_device_get_buffer(dev);100 int ret = get_buffer(dev); 112 101 if (ret != EOK) { 113 102 log_error("Failed to get device buffer: %s", … … 115 104 return ret; 116 105 } 117 ret = audio_device_start_playback(dev);106 ret = start_playback(dev); 118 107 if (ret != EOK) { 119 108 log_error("Failed to start playback: %s", 120 109 str_error(ret)); 121 audio_device_release_buffer(dev);110 release_buffer(dev); 122 111 return ret; 123 112 } 124 113 } 125 114 if (list_count(&dev->sink.sources) == 0) { 126 int ret = audio_device_stop_playback(dev);115 int ret = stop_playback(dev); 127 116 if (ret != EOK) { 128 117 log_error("Failed to start playback: %s", … … 131 120 } 132 121 dev->sink.format = AUDIO_FORMAT_ANY; 133 ret = audio_device_release_buffer(dev);122 ret = release_buffer(dev); 134 123 if (ret != EOK) { 135 124 log_error("Failed to release buffer: %s", … … 145 134 audio_device_t *dev = arg; 146 135 if (f) { /* Connected, f points to sink format */ 147 int ret = audio_device_get_buffer(dev);136 int ret = get_buffer(dev); 148 137 if (ret != EOK) { 149 138 log_error("Failed to get device buffer: %s", … … 151 140 return ret; 152 141 } 153 ret = audio_device_start_recording(dev);142 ret = start_recording(dev); 154 143 if (ret != EOK) { 155 144 log_error("Failed to start recording: %s", 156 145 str_error(ret)); 157 audio_device_release_buffer(dev);146 release_buffer(dev); 158 147 return ret; 159 148 } 160 149 dev->source.format = *f; 161 150 } else { /* Disconnected, f is NULL */ 162 int ret = audio_device_stop_recording(dev);151 int ret = stop_recording(dev); 163 152 if (ret != EOK) { 164 153 log_error("Failed to start recording: %s", … … 167 156 } 168 157 dev->sink.format = AUDIO_FORMAT_ANY; 169 ret = audio_device_release_buffer(dev);158 ret = release_buffer(dev); 170 159 if (ret != EOK) { 171 160 log_error("Failed to release buffer: %s", … … 178 167 } 179 168 169 static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void *arg) 170 { 171 /* Answer initial request */ 172 async_answer_0(iid, EOK); 173 audio_device_t *dev = arg; 174 assert(dev); 175 while (1) { 176 ipc_call_t call; 177 ipc_callid_t callid = async_get_call(&call); 178 async_answer_0(callid, EOK); 179 if (IPC_GET_IMETHOD(call) != IPC_FIRST_USER_METHOD) { 180 log_debug("Unknown event.\n"); 181 continue; 182 } 183 // Assume playback for now 184 if (dev->buffer.position) { 185 dev->buffer.position += dev->buffer.size / BUFFER_BLOCKS; 186 } 187 if (!dev->buffer.position || 188 dev->buffer.position >= dev->buffer.base + dev->buffer.size) 189 { 190 dev->buffer.position = dev->buffer.base; 191 } 192 audio_sink_mix_inputs( 193 &dev->sink, dev->buffer.base, 194 dev->buffer.size / BUFFER_BLOCKS); 195 196 } 197 //TODO implement 198 } 199 200 static int get_buffer(audio_device_t *dev) 201 { 202 assert(dev); 203 if (!dev->sess) { 204 log_debug("No connection to device"); 205 return EIO; 206 } 207 if (dev->buffer.base) { 208 log_debug("We already have a buffer"); 209 return EBUSY; 210 } 211 212 dev->buffer.size = 0; 213 214 async_exch_t *exch = async_exchange_begin(dev->sess); 215 const int ret = audio_pcm_get_buffer(exch, &dev->buffer.base, 216 &dev->buffer.size, &dev->buffer.id, device_event_callback, dev); 217 async_exchange_end(exch); 218 return ret; 219 } 220 221 #define CHECK_BUFFER_AND_CONNECTION() \ 222 do { \ 223 assert(dev); \ 224 if (!dev->sess) { \ 225 log_debug("No connection to device"); \ 226 return EIO; \ 227 } \ 228 if (!dev->buffer.base) { \ 229 log_debug("We don't have a buffer"); \ 230 return ENOENT; \ 231 } \ 232 } while (0) 233 234 235 static int release_buffer(audio_device_t *dev) 236 { 237 CHECK_BUFFER_AND_CONNECTION(); 238 239 async_exch_t *exch = async_exchange_begin(dev->sess); 240 const int ret = audio_pcm_release_buffer(exch, dev->buffer.id); 241 async_exchange_end(exch); 242 if (ret == EOK) { 243 dev->buffer.base = NULL; 244 dev->buffer.size = 0; 245 dev->buffer.position = NULL; 246 } 247 return ret; 248 } 249 250 static int start_playback(audio_device_t *dev) 251 { 252 CHECK_BUFFER_AND_CONNECTION(); 253 254 /* Fill the buffer first */ 255 audio_sink_mix_inputs(&dev->sink, dev->buffer.base, dev->buffer.size); 256 257 async_exch_t *exch = async_exchange_begin(dev->sess); 258 const int ret = audio_pcm_start_playback(exch, dev->buffer.id, 259 BUFFER_BLOCKS, dev->sink.format.channels, 260 dev->sink.format.sampling_rate, dev->sink.format.sample_format); 261 async_exchange_end(exch); 262 return ret; 263 } 264 265 static int stop_playback(audio_device_t *dev) 266 { 267 CHECK_BUFFER_AND_CONNECTION(); 268 269 async_exch_t *exch = async_exchange_begin(dev->sess); 270 const int ret = audio_pcm_stop_playback(exch, dev->buffer.id); 271 async_exchange_end(exch); 272 return ret; 273 } 274 275 static int start_recording(audio_device_t *dev) 276 { 277 CHECK_BUFFER_AND_CONNECTION(); 278 279 async_exch_t *exch = async_exchange_begin(dev->sess); 280 const int ret = audio_pcm_start_record(exch, dev->buffer.id, 281 BUFFER_BLOCKS, dev->sink.format.channels, 282 dev->sink.format.sampling_rate, dev->sink.format.sample_format); 283 async_exchange_end(exch); 284 return ret; 285 } 286 287 static int stop_recording(audio_device_t *dev) 288 { 289 CHECK_BUFFER_AND_CONNECTION(); 290 291 async_exch_t *exch = async_exchange_begin(dev->sess); 292 const int ret = audio_pcm_stop_record(exch, dev->buffer.id); 293 async_exchange_end(exch); 294 return ret; 295 } 180 296 181 297 /** -
uspace/srv/audio/hound/audio_device.h
rec49085 r992ef56 56 56 fibril_mutex_t guard; 57 57 fibril_condvar_t wc; 58 unsigned id; 58 59 void *base; 59 60 size_t size; 60 audio_format_t format; 61 void *available_base; 62 size_t available_size; 61 void *position; 63 62 } buffer; 64 63 audio_source_t source;
Note:
See TracChangeset
for help on using the changeset viewer.