1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2017-05-09 Urey first version 9 */ 10 11 #include <stdio.h> 12 #include <rthw.h> 13 #include <rtthread.h> 14 #include <rtdevice.h> 15 16 #include <drivers/audio.h> 17 18 #include "audio_pipe.h" 19 20 21 #define AUDIO_DEBUG 0 22 #if AUDIO_DEBUG 23 #define AUDIO_DBG(...) printf("[AUDIO]:"),printf(__VA_ARGS__) 24 #else 25 #define AUDIO_DBG(...) 26 #endif 27 28 static struct rt_audio_pipe audio_pipe; 29 30 static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) 31 { 32 rt_err_t result = RT_EOK; 33 rt_base_t level; 34 struct rt_audio_frame frame; 35 36 RT_ASSERT(audio != RT_NULL); 37 38 //check repaly queue is empty 39 if (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) != RT_EOK) 40 { 41 AUDIO_DBG("TX queue is empty\n"); 42 result = -RT_EEMPTY; 43 44 level = rt_hw_interrupt_disable(); 45 audio->replay->activated = RT_FALSE; 46 rt_hw_interrupt_enable(level); 47 48 goto _exit; 49 } 50 51 if (audio->ops->transmit != RT_NULL) 52 { 53 AUDIO_DBG("audio transmit...\n"); 54 if (audio->ops->transmit(audio, frame.data_ptr, RT_NULL, frame.data_size) != frame.data_size) 55 { 56 result = -RT_EBUSY; 57 58 goto _exit; 59 } 60 } 61 62 //pop the head frame... 63 rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); 64 65 _exit: return result; 66 } 67 68 static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio) 69 { 70 struct rt_audio_frame frame; 71 72 if (audio->replay == RT_NULL) 73 return -RT_EIO; 74 while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK) 75 { 76 //pop the head frame... 77 rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); 78 79 /* notify transmitted complete. */ 80 if (audio->parent.tx_complete != RT_NULL) 81 audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr); 82 } 83 84 return RT_EOK; 85 } 86 87 static rt_err_t _audio_dev_init(struct rt_device *dev) 88 { 89 rt_err_t result = RT_EOK; 90 struct rt_audio_device *audio; 91 92 RT_ASSERT(dev != RT_NULL); 93 audio = (struct rt_audio_device *) dev; 94 95 /* initialize replay & record */ 96 audio->replay = RT_NULL; 97 audio->record = RT_NULL; 98 99 /* apply configuration */ 100 if (audio->ops->init) 101 result = audio->ops->init(audio); 102 103 return result; 104 } 105 106 static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag) 107 { 108 struct rt_audio_device *audio; 109 110 RT_ASSERT(dev != RT_NULL); 111 audio = (struct rt_audio_device *) dev; 112 113 /* check device flag with the open flag */ 114 if ((oflag & RT_DEVICE_OFLAG_RDONLY) && !(dev->flag & RT_DEVICE_FLAG_RDONLY)) 115 return -RT_EIO; 116 if ((oflag & RT_DEVICE_OFLAG_WRONLY) && !(dev->flag & RT_DEVICE_FLAG_WRONLY)) 117 return -RT_EIO; 118 119 /* get open flags */ 120 dev->open_flag = oflag & 0xff; 121 122 /* initialize the Rx/Tx structure according to open flag */ 123 if (oflag & RT_DEVICE_OFLAG_WRONLY) 124 { 125 AUDIO_DBG("open audio device ,oflag = %x\n",oflag); 126 if (audio->replay == RT_NULL) 127 { 128 struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay)); 129 130 if (replay == RT_NULL) 131 { 132 AUDIO_DBG("request memory for replay error\n"); 133 return -RT_ENOMEM; 134 } 135 136 //init queue for audio replay 137 rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, CFG_AUDIO_REPLAY_QUEUE_COUNT / 2, RT_NULL); 138 139 replay->activated = RT_FALSE; 140 audio->replay = replay; 141 } 142 143 dev->open_flag |= RT_DEVICE_OFLAG_WRONLY; 144 } 145 146 if (oflag & RT_DEVICE_OFLAG_RDONLY) 147 { 148 if (audio->record == RT_NULL) 149 { 150 struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record)); 151 152 if (record == RT_NULL) 153 { 154 AUDIO_DBG("request memory for record error\n"); 155 return -RT_ENOMEM; 156 } 157 158 //init pipe for record 159 { 160 rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE); 161 162 if (buf == RT_NULL) 163 { 164 rt_free(record); 165 AUDIO_DBG("request pipe memory error\n"); 166 167 return -RT_ENOMEM; 168 } 169 170 rt_audio_pipe_init(&audio_pipe, "recpipe", (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD), buf, 171 CFG_AUDIO_RECORD_PIPE_SIZE); 172 } 173 174 record->activated = RT_FALSE; 175 audio->record = record; 176 } 177 178 //open record pipe 179 if (audio->record != RT_NULL) 180 { 181 rt_device_open(RT_DEVICE(&audio_pipe), RT_DEVICE_OFLAG_RDONLY); 182 } 183 184 dev->open_flag |= RT_DEVICE_OFLAG_RDONLY; 185 } 186 187 return RT_EOK; 188 } 189 190 static rt_err_t _audio_dev_close(struct rt_device *dev) 191 { 192 struct rt_audio_device *audio; 193 RT_ASSERT(dev != RT_NULL); 194 audio = (struct rt_audio_device *) dev; 195 196 //shutdown the lower device 197 if (audio->ops->shutdown != RT_NULL) 198 audio->ops->shutdown(audio); 199 200 if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) 201 { 202 struct rt_audio_frame frame; 203 //stop replay stream 204 audio->ops->stop(audio, AUDIO_STREAM_REPLAY); 205 206 //flush all frame 207 while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK) 208 { 209 //pop the head frame... 210 rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER); 211 212 /* notify transmitted complete. */ 213 if (audio->parent.tx_complete != RT_NULL) 214 audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr); 215 } 216 217 dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY; 218 } 219 220 if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY) 221 { 222 //stop record stream 223 audio->ops->stop(audio, AUDIO_STREAM_RECORD); 224 225 //close record pipe 226 if (audio->record != RT_NULL) 227 rt_device_close(RT_DEVICE(&audio_pipe)); 228 229 dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY; 230 } 231 232 return RT_EOK; 233 } 234 235 static rt_size_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) 236 { 237 struct rt_audio_device *audio; 238 RT_ASSERT(dev != RT_NULL); 239 audio = (struct rt_audio_device *) dev; 240 if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL)) 241 return 0; 242 243 return rt_device_read(RT_DEVICE(&audio_pipe), pos, buffer, size); 244 } 245 246 static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) 247 { 248 rt_err_t result = RT_EOK; 249 rt_base_t level; 250 struct rt_audio_device *audio; 251 252 RT_ASSERT(dev != RT_NULL); 253 audio = (struct rt_audio_device *) dev; 254 255 if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL)) 256 return 0; 257 258 AUDIO_DBG("audio write : pos = %d,buffer = %x,size = %d\n",pos,(rt_uint32_t)buffer,size); 259 //push a new frame to tx queue 260 { 261 result = rt_data_queue_push(&audio->replay->queue, buffer, size, 262 RT_WAITING_FOREVER); 263 if (result != RT_EOK) 264 { 265 AUDIO_DBG("TX frame queue push error\n"); 266 rt_set_errno(-RT_EFULL); 267 return 0; 268 } 269 } 270 271 //check tx state... 272 level = rt_hw_interrupt_disable(); 273 if (audio->replay->activated != RT_TRUE) 274 { 275 audio->replay->activated = RT_TRUE; 276 rt_hw_interrupt_enable(level); 277 278 _audio_send_replay_frame(audio); 279 } 280 else 281 { 282 rt_hw_interrupt_enable(level); 283 } 284 285 return size; 286 } 287 288 static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args) 289 { 290 rt_err_t result = RT_EOK; 291 struct rt_audio_device *audio; 292 RT_ASSERT(dev != RT_NULL); 293 audio = (struct rt_audio_device *) dev; 294 295 //dev stat... 296 switch (cmd) 297 { 298 case AUDIO_CTL_GETCAPS: 299 { 300 struct rt_audio_caps *caps = (struct rt_audio_caps *) args; 301 302 AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); 303 if (audio->ops->getcaps != RT_NULL) 304 { 305 result = audio->ops->getcaps(audio, caps); 306 } 307 } 308 break; 309 case AUDIO_CTL_CONFIGURE: 310 { 311 struct rt_audio_caps *caps = (struct rt_audio_caps *) args; 312 313 AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type); 314 if (audio->ops->configure != RT_NULL) 315 { 316 result = audio->ops->configure(audio, caps); 317 } 318 } 319 320 break; 321 case AUDIO_CTL_SHUTDOWN: 322 { 323 AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n"); 324 325 if (audio->ops->shutdown != RT_NULL) 326 result = audio->ops->shutdown(audio); 327 328 //flush replay frame... 329 _audio_flush_replay_frame(audio); 330 } 331 break; 332 333 case AUDIO_CTL_START: 334 { 335 int stream = *(int *) args; 336 337 AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream); 338 if (audio->ops->start != RT_NULL) 339 result = audio->ops->start(audio, stream); 340 } 341 break; 342 case AUDIO_CTL_STOP: 343 { 344 int stream = *(int *) args; 345 346 AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream); 347 if (audio->ops->start != RT_NULL) 348 result = audio->ops->stop(audio, stream); 349 350 if (stream == AUDIO_STREAM_REPLAY) 351 { 352 _audio_flush_replay_frame(audio); 353 } 354 } 355 break; 356 case AUDIO_CTL_PAUSE: 357 { 358 int stream = *(int *) args; 359 360 AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream); 361 if (audio->ops->start != RT_NULL) 362 result = audio->ops->suspend(audio, stream); 363 } 364 break; 365 case AUDIO_CTL_RESUME: 366 { 367 int stream = *(int *) args; 368 369 AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream); 370 if (audio->ops->start != RT_NULL) 371 result = audio->ops->resume(audio, stream); 372 373 //resume tx frame... 374 if (stream == AUDIO_STREAM_REPLAY) 375 _audio_send_replay_frame(audio); 376 } 377 break; 378 case AUDIO_CTL_ALLOCBUFFER: 379 { 380 struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *) args; 381 382 if (desc) 383 { 384 desc->data_size = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2; 385 desc->data_ptr = rt_mp_alloc(&audio->mp, RT_WAITING_FOREVER); 386 387 result = RT_EOK; 388 } 389 else result = -RT_EIO; 390 } 391 break; 392 case AUDIO_CTL_FREEBUFFER: 393 { 394 rt_uint8_t *data_ptr = (rt_uint8_t *) args; 395 if (data_ptr) 396 rt_mp_free(data_ptr); 397 } 398 break; 399 default: 400 result = audio->ops->control(audio, cmd, args); 401 break; 402 } 403 404 return result; 405 } 406 407 #ifdef RT_USING_DEVICE_OPS 408 const static struct rt_device_ops audio_ops = 409 { 410 _audio_dev_init, 411 _audio_dev_open, 412 _audio_dev_close, 413 _audio_dev_read, 414 _audio_dev_write, 415 _audio_dev_control 416 }; 417 #endif 418 419 rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data) 420 { 421 struct rt_device *device; 422 RT_ASSERT(audio != RT_NULL); 423 device = &(audio->parent); 424 425 device->type = RT_Device_Class_Sound; 426 device->rx_indicate = RT_NULL; 427 device->tx_complete = RT_NULL; 428 429 #ifdef RT_USING_DEVICE_OPS 430 device->ops = &audio_ops; 431 #else 432 device->init = _audio_dev_init; 433 device->open = _audio_dev_open; 434 device->close = _audio_dev_close; 435 device->read = _audio_dev_read; 436 device->write = _audio_dev_write; 437 device->control = _audio_dev_control; 438 #endif 439 device->user_data = data; 440 441 //init memory pool for replay 442 { 443 rt_uint8_t *mempool = rt_malloc(AUDIO_DEVICE_DECODE_MP_SZ); 444 rt_mp_init(&audio->mp, "adu_mp", mempool, AUDIO_DEVICE_DECODE_MP_SZ, 445 AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2); 446 } 447 448 /* register a character device */ 449 return rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE); 450 } 451 452 int rt_audio_samplerate_to_speed(rt_uint32_t bitValue) 453 { 454 int speed = 0; 455 switch (bitValue) 456 { 457 case AUDIO_SAMP_RATE_8K: 458 speed = 8000; 459 break; 460 case AUDIO_SAMP_RATE_11K: 461 speed = 11052; 462 break; 463 case AUDIO_SAMP_RATE_16K: 464 speed = 16000; 465 break; 466 case AUDIO_SAMP_RATE_22K: 467 speed = 22050; 468 break; 469 case AUDIO_SAMP_RATE_32K: 470 speed = 32000; 471 break; 472 case AUDIO_SAMP_RATE_44K: 473 speed = 44100; 474 break; 475 case AUDIO_SAMP_RATE_48K: 476 speed = 48000; 477 break; 478 case AUDIO_SAMP_RATE_96K: 479 speed = 96000; 480 break; 481 case AUDIO_SAMP_RATE_128K: 482 speed = 128000; 483 break; 484 case AUDIO_SAMP_RATE_160K: 485 speed = 160000; 486 break; 487 case AUDIO_SAMP_RATE_172K: 488 speed = 176400; 489 break; 490 case AUDIO_SAMP_RATE_192K: 491 speed = 192000; 492 break; 493 default: 494 495 break; 496 } 497 498 return speed; 499 } 500 501 rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format) 502 { 503 switch (format) 504 { 505 case AUDIO_FMT_PCM_U8: 506 case AUDIO_FMT_PCM_S8: 507 return 8; 508 case AUDIO_FMT_PCM_S16_LE: 509 case AUDIO_FMT_PCM_S16_BE: 510 case AUDIO_FMT_PCM_U16_LE: 511 case AUDIO_FMT_PCM_U16_BE: 512 return 16; 513 default: 514 return 32; 515 }; 516 } 517 518 void rt_audio_tx_complete(struct rt_audio_device *audio, rt_uint8_t *pbuf) 519 { 520 rt_err_t result; 521 AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf); 522 523 //try to send all frame 524 do 525 { 526 result = _audio_send_replay_frame(audio); 527 } while (result == RT_EOK); 528 529 /* notify transmitted complete. */ 530 if (audio->parent.tx_complete != RT_NULL) 531 audio->parent.tx_complete(&audio->parent, (void *) pbuf); 532 } 533 534 void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len) 535 { 536 //save data to record pipe 537 rt_device_write(RT_DEVICE(RT_DEVICE(&audio_pipe)), 0, pbuf, len); 538 539 /* invoke callback */ 540 if (audio->parent.rx_indicate != RT_NULL) 541 audio->parent.rx_indicate(&audio->parent, len); 542 } 543 544