key_tone.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file key tone
  8. */
  9. #define SYS_LOG_DOMAIN "keytone"
  10. #include <os_common_api.h>
  11. #include <audio_system.h>
  12. #include <media_player.h>
  13. #include <buffer_stream.h>
  14. #include <file_stream.h>
  15. #include <app_manager.h>
  16. #include <mem_manager.h>
  17. #include <tts_manager.h>
  18. #include <audio_track.h>
  19. #include <ringbuff_stream.h>
  20. #ifdef CONFIG_SD_FS
  21. #include <sdfs.h>
  22. #endif
  23. struct key_tone_manager_t {
  24. io_stream_t tone_stream;
  25. uint8_t key_tone_cnt;
  26. struct acts_ringbuf *tone_ringbuf;
  27. struct audio_track_t *keytone_track;
  28. os_delayed_work play_work;
  29. os_delayed_work stop_work;
  30. char key_tone_name[12];
  31. };
  32. static struct key_tone_manager_t key_tone_manager;
  33. static void _key_tone_track_callback(uint8_t event, void *user_data)
  34. {
  35. }
  36. static io_stream_t _key_tone_create_stream(uint8_t *key_tone_file)
  37. {
  38. int ret = 0;
  39. io_stream_t input_stream = NULL;
  40. struct buffer_t buffer;
  41. if (sd_fmap(key_tone_file, (void **)&buffer.base, &buffer.length) != 0) {
  42. goto exit;
  43. }
  44. input_stream = ringbuff_stream_create_ext(buffer.base, buffer.length);
  45. if (!input_stream) {
  46. goto exit;
  47. }
  48. ret = stream_open(input_stream, MODE_IN_OUT);
  49. if (ret) {
  50. stream_destroy(input_stream);
  51. input_stream = NULL;
  52. goto exit;
  53. }
  54. stream_write(input_stream, NULL, buffer.length);
  55. stream_write(input_stream, NULL, 0);
  56. exit:
  57. SYS_LOG_INF("%p\n", input_stream);
  58. return input_stream;
  59. }
  60. static struct acts_ringbuf *_key_tone_create_ringbuff(uint8_t *key_tone_file)
  61. {
  62. struct acts_ringbuf *ringbuff = NULL;
  63. struct buffer_t buffer;
  64. #ifdef CONFIG_SD_FS
  65. if (sd_fmap(key_tone_file, (void **)&buffer.base, &buffer.length) != 0) {
  66. goto exit;
  67. }
  68. #endif
  69. ringbuff = acts_ringbuf_init_ext(buffer.base, buffer.length);
  70. if (!ringbuff) {
  71. SYS_LOG_ERR("create failed\n");
  72. goto exit;
  73. }
  74. acts_ringbuf_fill_none(ringbuff, buffer.length);
  75. SYS_LOG_INF("ringbuff %p\n", ringbuff);
  76. exit:
  77. return ringbuff;
  78. }
  79. static void _keytone_manager_play_work(os_work *work)
  80. {
  81. struct key_tone_manager_t *manager = &key_tone_manager;
  82. struct audio_track_t *keytone_track;
  83. audio_system_mutex_lock();
  84. keytone_track = audio_system_get_track();
  85. /**audio_track already open*/
  86. if (keytone_track) {
  87. io_stream_t tone_stream = _key_tone_create_stream(manager->key_tone_name);
  88. if (!tone_stream) {
  89. goto exit;
  90. }
  91. audio_track_set_mix_stream(keytone_track, tone_stream, 8, 1, AUDIO_STREAM_TTS);
  92. manager->tone_stream = tone_stream;
  93. } else {
  94. struct acts_ringbuf *tone_ringbuf = _key_tone_create_ringbuff(manager->key_tone_name);
  95. if (!tone_ringbuf) {
  96. goto exit;
  97. }
  98. manager->tone_ringbuf = tone_ringbuf;
  99. keytone_track = audio_track_create(AUDIO_STREAM_TTS, 8,
  100. AUDIO_FORMAT_PCM_16_BIT, AUDIO_MODE_MONO,
  101. tone_ringbuf,
  102. _key_tone_track_callback, manager);
  103. if (!keytone_track) {
  104. goto exit;
  105. }
  106. audio_track_start(keytone_track);
  107. }
  108. manager->keytone_track = keytone_track;
  109. exit:
  110. audio_system_mutex_unlock();
  111. }
  112. static void _keytone_manager_stop_work(os_work *work)
  113. {
  114. struct key_tone_manager_t *manager = &key_tone_manager;
  115. audio_system_mutex_lock();
  116. if (manager->keytone_track) {
  117. if (manager->tone_ringbuf) {
  118. audio_track_flush(manager->keytone_track);
  119. audio_track_stop(manager->keytone_track);
  120. audio_track_destory(manager->keytone_track);
  121. acts_ringbuf_destroy_ext(manager->tone_ringbuf);
  122. manager->keytone_track = NULL;
  123. } else if(manager->tone_stream){
  124. audio_track_set_mix_stream(manager->keytone_track, NULL, 8, 1, AUDIO_STREAM_TTS);
  125. stream_close(manager->tone_stream);
  126. stream_destroy(manager->tone_stream);
  127. manager->keytone_track = NULL;
  128. }
  129. }
  130. manager->tone_stream = NULL;
  131. manager->keytone_track = NULL;
  132. manager->tone_ringbuf = NULL;
  133. manager->key_tone_cnt--;
  134. if (manager->key_tone_cnt > 0) {
  135. os_delayed_work_submit(&manager->play_work, OS_NO_WAIT);
  136. os_delayed_work_submit(&manager->stop_work, 150);
  137. }
  138. audio_system_mutex_unlock();
  139. }
  140. int key_tone_play(const char *file_name)
  141. {
  142. struct key_tone_manager_t *manager = &key_tone_manager;
  143. #ifdef CONFIG_SYS_IRQ_LOCK
  144. SYS_IRQ_FLAGS flags;
  145. sys_irq_lock(&flags);
  146. #endif
  147. audio_system_mutex_lock();
  148. strcpy(manager->key_tone_name, file_name);
  149. audio_system_mutex_unlock();
  150. if (!manager->key_tone_cnt) {
  151. manager->key_tone_cnt++;
  152. os_delayed_work_submit(&manager->play_work, OS_NO_WAIT);
  153. os_delayed_work_submit(&manager->stop_work, 150);
  154. } else {
  155. manager->key_tone_cnt++;
  156. }
  157. #ifdef CONFIG_SYS_IRQ_LOCK
  158. sys_irq_unlock(&flags);
  159. #endif
  160. return 0;
  161. }
  162. int key_tone_manager_init(void)
  163. {
  164. memset(&key_tone_manager, 0, sizeof(struct key_tone_manager_t));
  165. os_delayed_work_init(&key_tone_manager.play_work, _keytone_manager_play_work);
  166. os_delayed_work_init(&key_tone_manager.stop_work, _keytone_manager_stop_work);
  167. return 0;
  168. }