audio_play.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. extern void local_sdk_speaker_set_pa_mode(int mode);
  7. extern void local_sdk_speaker_set_ap_mode(int mode);
  8. extern void local_sdk_speaker_clean_buf_data();
  9. extern void local_sdk_speaker_set_volume(int volume);
  10. extern int local_sdk_speaker_feed_pcm_data(unsigned char *buf, int size);
  11. extern void local_sdk_speaker_finish_buf_data();
  12. extern void CommandResponse(int fd, const char *res);
  13. static pthread_mutex_t AudioPlayMutex = PTHREAD_MUTEX_INITIALIZER;
  14. static int AudioPlayFd = -1;
  15. static char waveFile[256];
  16. static int Volume = 0;
  17. int PlayPCM(char *file, int vol) {
  18. static const int waveHeaderLength = 44;
  19. static const int bufLength = 640;
  20. unsigned char buf[bufLength];
  21. const unsigned char cmp[] = {
  22. 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
  23. 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x80, 0x3e, 0x00, 0x00,
  24. 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
  25. };
  26. fprintf(stderr, "[command] aplay: file:%s\n", file);
  27. FILE *fp = fopen(file, "rb");
  28. if(fp == NULL) {
  29. fprintf(stderr, "[command] aplay err: fopen %s failed!\n", file);
  30. return -1;
  31. } else {
  32. size_t size = fread(buf, 1, waveHeaderLength, fp);
  33. if(size != waveHeaderLength) {
  34. fprintf(stderr, "[command] aplay err: header size error\n");
  35. }
  36. buf[4] = buf[5] = buf[6] = buf[7] = 0;
  37. if(memcmp(buf, cmp, waveHeaderLength - 4)) {
  38. fprintf(stderr, "[command] aplay err: header error\n");
  39. }
  40. local_sdk_speaker_clean_buf_data();
  41. local_sdk_speaker_set_volume(vol);
  42. if(!local_sdk_speaker_set_pa_mode) {
  43. local_sdk_speaker_set_ap_mode(3);
  44. fprintf(stderr, "[command] aplay: set ap mode 3\n");
  45. }
  46. if(!local_sdk_speaker_set_ap_mode) {
  47. local_sdk_speaker_set_pa_mode(3);
  48. fprintf(stderr, "[command] aplay: set pa mode 3\n");
  49. }
  50. while(!feof(fp)) {
  51. size = fread(buf, 1, bufLength, fp);
  52. if (size <= 0) break;
  53. while(local_sdk_speaker_feed_pcm_data(buf, size)) usleep(100 * 1000);
  54. }
  55. fclose(fp);
  56. usleep(2 * 1000 * 1000);
  57. local_sdk_speaker_finish_buf_data();
  58. local_sdk_speaker_set_volume(0);
  59. if(!local_sdk_speaker_set_pa_mode) {
  60. local_sdk_speaker_set_ap_mode(0);
  61. }
  62. if(!local_sdk_speaker_set_ap_mode) {
  63. local_sdk_speaker_set_pa_mode(0);
  64. }
  65. }
  66. fprintf(stderr, "[command] aplay: finish\n");
  67. return 0;
  68. }
  69. static void *AudioPlayThread() {
  70. while(1) {
  71. pthread_mutex_lock(&AudioPlayMutex);
  72. if(AudioPlayFd >= 0) {
  73. int res = PlayPCM(waveFile, Volume);
  74. CommandResponse(AudioPlayFd, res ? "error" : "ok");
  75. }
  76. AudioPlayFd = -1;
  77. }
  78. }
  79. char *AudioPlay(int fd, char *tokenPtr) {
  80. if(AudioPlayFd >= 0) {
  81. fprintf(stderr, "[command] aplay err: Previous file is still playing. %d %d\n", AudioPlayFd, fd);
  82. return "error";
  83. }
  84. char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
  85. if(!p) {
  86. fprintf(stderr, "[command] aplay err: usage : aplay <wave file> [<volume>]\n");
  87. return "error";
  88. }
  89. strncpy(waveFile, p, 255);
  90. p = strtok_r(NULL, " \t\r\n", &tokenPtr);
  91. Volume = 40;
  92. if(p) Volume = atoi(p);
  93. AudioPlayFd = fd;
  94. pthread_mutex_unlock(&AudioPlayMutex);
  95. return NULL;
  96. }
  97. static void __attribute ((constructor)) AudioPlayInit(void) {
  98. pthread_mutex_lock(&AudioPlayMutex);
  99. pthread_t thread;
  100. if(pthread_create(&thread, NULL, AudioPlayThread, NULL)) {
  101. fprintf(stderr, "pthread_create error\n");
  102. pthread_mutex_unlock(&AudioPlayMutex);
  103. return;
  104. }
  105. }