wav_play.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <finsh.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include "audio_device.h"
  8. #define BUFSZ 2048
  9. struct RIFF_HEADER_DEF
  10. {
  11. char riff_id[4]; // 'R','I','F','F'
  12. uint32_t riff_size;
  13. char riff_format[4]; // 'W','A','V','E'
  14. };
  15. struct WAVE_FORMAT_DEF
  16. {
  17. uint16_t FormatTag;
  18. uint16_t Channels;
  19. uint32_t SamplesPerSec;
  20. uint32_t AvgBytesPerSec;
  21. uint16_t BlockAlign;
  22. uint16_t BitsPerSample;
  23. };
  24. struct FMT_BLOCK_DEF
  25. {
  26. char fmt_id[4]; // 'f','m','t',' '
  27. uint32_t fmt_size;
  28. struct WAVE_FORMAT_DEF wav_format;
  29. };
  30. struct DATA_BLOCK_DEF
  31. {
  32. char data_id[4]; // 'R','I','F','F'
  33. uint32_t data_size;
  34. };
  35. struct wav_info
  36. {
  37. struct RIFF_HEADER_DEF header;
  38. struct FMT_BLOCK_DEF fmt_block;
  39. struct DATA_BLOCK_DEF data_block;
  40. };
  41. static char file_name[32];
  42. void wavplay_thread_entry(void *parameter)
  43. {
  44. FILE *fp = NULL;
  45. uint16_t *buffer = NULL;
  46. struct wav_info *info = NULL;
  47. fp = fopen(file_name, "rb");
  48. if (!fp)
  49. {
  50. printf("open file failed!\n");
  51. goto __exit;
  52. }
  53. info = (struct wav_info *) malloc(sizeof(*info));
  54. if (!info) goto __exit;
  55. if (fread(&(info->header), sizeof(struct RIFF_HEADER_DEF), 1, fp) != 1) goto __exit;
  56. if (fread(&(info->fmt_block), sizeof(struct FMT_BLOCK_DEF), 1, fp) != 1) goto __exit;
  57. if (fread(&(info->data_block), sizeof(struct DATA_BLOCK_DEF), 1, fp) != 1) goto __exit;
  58. printf("wav information:\n");
  59. printf("samplerate %u\n", info->fmt_block.wav_format.SamplesPerSec);
  60. printf("channel %u\n", info->fmt_block.wav_format.Channels);
  61. audio_device_init();
  62. audio_device_open();
  63. audio_device_set_rate(info->fmt_block.wav_format.SamplesPerSec);
  64. while (!feof(fp))
  65. {
  66. int length;
  67. buffer = (uint16_t *)audio_device_get_buffer(RT_NULL);
  68. length = fread(buffer, 1, BUFSZ, fp);
  69. if (length)
  70. {
  71. if (info->fmt_block.wav_format.Channels == 1)
  72. {
  73. /* extend to stereo channels */
  74. int index;
  75. uint16_t *ptr;
  76. ptr = (uint16_t *)((uint8_t *)buffer + BUFSZ * 2);
  77. for (index = 1; index < BUFSZ / 2; index ++)
  78. {
  79. *ptr = *(ptr - 1) = buffer[BUFSZ / 2 - index];
  80. ptr -= 2;
  81. }
  82. length = length * 2;
  83. }
  84. audio_device_write((uint8_t *)buffer, length);
  85. }
  86. else
  87. {
  88. audio_device_put_buffer((uint8_t *)buffer);
  89. break;
  90. }
  91. }
  92. audio_device_close();
  93. __exit:
  94. if (fp) fclose(fp);
  95. if (info) free(info);
  96. }
  97. int wavplay(int argc, char **argv)
  98. {
  99. rt_thread_t tid = RT_NULL;
  100. if (argc != 2)
  101. {
  102. printf("Usage:\n");
  103. printf("wavplay song.wav\n");
  104. return 0;
  105. }
  106. memset(file_name, 0, sizeof(file_name));
  107. memcpy(file_name, argv[1], strlen(argv[1]));
  108. tid = rt_thread_create("wayplay",
  109. wavplay_thread_entry,
  110. RT_NULL,
  111. 1024 * 8,
  112. 22,
  113. 10);
  114. if (tid != RT_NULL)
  115. rt_thread_startup(tid);
  116. }
  117. MSH_CMD_EXPORT(wavplay, wavplay song.wav);