Easy playback library for AUDIO_GRBoard.

Dependents:   GR-PEACH_Audio_WAV_PwmOut GR-Boards_Audio_WAV

Committer:
dkato
Date:
Tue Jul 03 05:12:29 2018 +0000
Revision:
1:fdd79b99ba73
Parent:
0:9956e2ed09da
Child:
2:6c46c61630b3
Add decoder EasyDec_Mov

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:9956e2ed09da 1 /* mbed EasyPlayback Library
dkato 0:9956e2ed09da 2 * Copyright (C) 2017 dkato
dkato 0:9956e2ed09da 3 *
dkato 0:9956e2ed09da 4 * Licensed under the Apache License, Version 2.0 (the "License");
dkato 0:9956e2ed09da 5 * you may not use this file except in compliance with the License.
dkato 0:9956e2ed09da 6 * You may obtain a copy of the License at
dkato 0:9956e2ed09da 7 *
dkato 0:9956e2ed09da 8 * http://www.apache.org/licenses/LICENSE-2.0
dkato 0:9956e2ed09da 9 *
dkato 0:9956e2ed09da 10 * Unless required by applicable law or agreed to in writing, software
dkato 0:9956e2ed09da 11 * distributed under the License is distributed on an "AS IS" BASIS,
dkato 0:9956e2ed09da 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dkato 0:9956e2ed09da 13 * See the License for the specific language governing permissions and
dkato 0:9956e2ed09da 14 * limitations under the License.
dkato 0:9956e2ed09da 15 */
dkato 0:9956e2ed09da 16
dkato 0:9956e2ed09da 17 #include "mbed.h"
dkato 0:9956e2ed09da 18 #include "dcache-control.h"
dkato 0:9956e2ed09da 19 #include "EasyPlayback.h"
dkato 0:9956e2ed09da 20
dkato 1:fdd79b99ba73 21 EasyPlayback::EasyPlayback(audio_type_t type) :
dkato 1:fdd79b99ba73 22 _buff_index(0), _type(type), _skip(false), _pause(false), _init_end(false)
dkato 0:9956e2ed09da 23 {
dkato 1:fdd79b99ba73 24 _audio_ssif = NULL;
dkato 1:fdd79b99ba73 25 if (_type == AUDIO_TPYE_SSIF) {
dkato 1:fdd79b99ba73 26 _audio_buff_size = 4096;
dkato 1:fdd79b99ba73 27 _audio_ssif = new AUDIO_GRBoard(0x80, (AUDIO_WRITE_BUFF_NUM - 1), 0);
dkato 1:fdd79b99ba73 28 _audio = _audio_ssif;
dkato 1:fdd79b99ba73 29 } else if (_type == AUDIO_TPYE_SPDIF) {
dkato 1:fdd79b99ba73 30 MBED_ASSERT(false);
dkato 1:fdd79b99ba73 31 } else {
dkato 1:fdd79b99ba73 32 MBED_ASSERT(false);
dkato 1:fdd79b99ba73 33 }
dkato 1:fdd79b99ba73 34 _heap_buf = new uint8_t[_audio_buff_size * AUDIO_WRITE_BUFF_NUM + 31];
dkato 1:fdd79b99ba73 35 _audio_buf = (uint8_t *)(((uint32_t)_heap_buf + 31ul) & ~31ul);
dkato 0:9956e2ed09da 36 }
dkato 0:9956e2ed09da 37
dkato 0:9956e2ed09da 38 EasyPlayback::~EasyPlayback()
dkato 0:9956e2ed09da 39 {
dkato 1:fdd79b99ba73 40 if (_audio_ssif != NULL) {
dkato 1:fdd79b99ba73 41 delete _audio_ssif;
dkato 1:fdd79b99ba73 42 }
dkato 1:fdd79b99ba73 43 #if (R_BSP_SPDIF_ENABLE == 1)
dkato 1:fdd79b99ba73 44 if (_audio_spdif != NULL) {
dkato 1:fdd79b99ba73 45 delete _audio_spdif;
dkato 1:fdd79b99ba73 46 }
dkato 1:fdd79b99ba73 47 #endif
dkato 0:9956e2ed09da 48 delete [] _heap_buf;
dkato 0:9956e2ed09da 49 }
dkato 0:9956e2ed09da 50
dkato 0:9956e2ed09da 51 bool EasyPlayback::get_tag(const char* filename, char* p_title, char* p_artist, char* p_album, uint16_t tag_size)
dkato 0:9956e2ed09da 52 {
dkato 1:fdd79b99ba73 53 FILE * fp = NULL;
dkato 0:9956e2ed09da 54 EasyDecoder * decoder;
dkato 0:9956e2ed09da 55 bool ret = false;
dkato 0:9956e2ed09da 56
dkato 0:9956e2ed09da 57 decoder = create_decoer_class(filename);
dkato 0:9956e2ed09da 58 if (decoder == NULL) {
dkato 0:9956e2ed09da 59 return false;
dkato 0:9956e2ed09da 60 }
dkato 0:9956e2ed09da 61
dkato 0:9956e2ed09da 62 fp = fopen(filename, "r");
dkato 1:fdd79b99ba73 63 if (fp == NULL) {
dkato 1:fdd79b99ba73 64 // do nothing
dkato 1:fdd79b99ba73 65 } else if (decoder->AnalyzeHeder(p_title, p_artist, p_album, tag_size, fp) != false) {
dkato 0:9956e2ed09da 66 ret = true;
dkato 0:9956e2ed09da 67 }
dkato 0:9956e2ed09da 68 delete decoder;
dkato 1:fdd79b99ba73 69 if (fp != NULL) {
dkato 1:fdd79b99ba73 70 fclose(fp);
dkato 1:fdd79b99ba73 71 }
dkato 0:9956e2ed09da 72
dkato 0:9956e2ed09da 73 return ret;
dkato 0:9956e2ed09da 74 }
dkato 0:9956e2ed09da 75
dkato 0:9956e2ed09da 76 bool EasyPlayback::play(const char* filename)
dkato 0:9956e2ed09da 77 {
dkato 0:9956e2ed09da 78 const rbsp_data_conf_t audio_write_async_ctl = {NULL, NULL};
dkato 1:fdd79b99ba73 79 size_t audio_data_size;
dkato 1:fdd79b99ba73 80 FILE * fp = NULL;
dkato 0:9956e2ed09da 81 uint8_t * p_buf;
dkato 1:fdd79b99ba73 82 uint32_t read_size;
dkato 1:fdd79b99ba73 83 uint32_t i;
dkato 0:9956e2ed09da 84 EasyDecoder * decoder;
dkato 0:9956e2ed09da 85 bool ret = false;
dkato 1:fdd79b99ba73 86 uint32_t padding_size;
dkato 0:9956e2ed09da 87
dkato 0:9956e2ed09da 88 decoder = create_decoer_class(filename);
dkato 0:9956e2ed09da 89 if (decoder == NULL) {
dkato 0:9956e2ed09da 90 return false;
dkato 0:9956e2ed09da 91 }
dkato 0:9956e2ed09da 92
dkato 0:9956e2ed09da 93 if (!_init_end) {
dkato 1:fdd79b99ba73 94 _audio->power();
dkato 1:fdd79b99ba73 95 _audio->outputVolume(1.0, 1.0);
dkato 0:9956e2ed09da 96 _init_end = true;
dkato 0:9956e2ed09da 97 }
dkato 0:9956e2ed09da 98
dkato 0:9956e2ed09da 99 _skip = false;
dkato 0:9956e2ed09da 100 fp = fopen(filename, "r");
dkato 1:fdd79b99ba73 101 if (fp == NULL) {
dkato 1:fdd79b99ba73 102 // do nothing
dkato 1:fdd79b99ba73 103 } else if (decoder->AnalyzeHeder(NULL, NULL, NULL, 0, fp) == false) {
dkato 0:9956e2ed09da 104 // do nothing
dkato 0:9956e2ed09da 105 } else if ((decoder->GetChannel() != 2)
dkato 1:fdd79b99ba73 106 || (_audio->format(decoder->GetBlockSize()) == false)
dkato 1:fdd79b99ba73 107 || (_audio->frequency(decoder->GetSamplingRate()) == false)) {
dkato 0:9956e2ed09da 108 // do nothing
dkato 0:9956e2ed09da 109 } else {
dkato 1:fdd79b99ba73 110 if ((_type == AUDIO_TPYE_SPDIF) && (decoder->GetBlockSize() == 16)) {
dkato 1:fdd79b99ba73 111 padding_size = 2;
dkato 1:fdd79b99ba73 112 read_size = _audio_buff_size / 2;
dkato 1:fdd79b99ba73 113 } else if ((decoder->GetBlockSize() == 20) || (decoder->GetBlockSize() == 24)) {
dkato 1:fdd79b99ba73 114 padding_size = 1;
dkato 1:fdd79b99ba73 115 read_size = _audio_buff_size * 3 / 4;
dkato 1:fdd79b99ba73 116 } else {
dkato 1:fdd79b99ba73 117 padding_size = 0;
dkato 1:fdd79b99ba73 118 read_size = _audio_buff_size;
dkato 1:fdd79b99ba73 119 }
dkato 1:fdd79b99ba73 120 setvbuf(fp, NULL, _IONBF, 0); // unbuffered
dkato 1:fdd79b99ba73 121
dkato 1:fdd79b99ba73 122 while (true) {
dkato 0:9956e2ed09da 123 while ((_pause) && (!_skip)) {
dkato 0:9956e2ed09da 124 Thread::wait(100);
dkato 0:9956e2ed09da 125 }
dkato 0:9956e2ed09da 126 if (_skip) {
dkato 0:9956e2ed09da 127 break;
dkato 0:9956e2ed09da 128 }
dkato 1:fdd79b99ba73 129 p_buf = &_audio_buf[_audio_buff_size * _buff_index];
dkato 1:fdd79b99ba73 130 audio_data_size = decoder->GetNextData(p_buf, read_size);
dkato 0:9956e2ed09da 131 if (audio_data_size > 0) {
dkato 1:fdd79b99ba73 132 if (padding_size != 0) {
dkato 1:fdd79b99ba73 133 int idx_w = _audio_buff_size - 1;
dkato 1:fdd79b99ba73 134 int idx_r = read_size - 1;
dkato 1:fdd79b99ba73 135 uint32_t block_byte = (decoder->GetBlockSize() + 7) / 8;
dkato 1:fdd79b99ba73 136
dkato 1:fdd79b99ba73 137 // fill the shortfall with 0
dkato 1:fdd79b99ba73 138 for (i = audio_data_size; i < read_size; i++) {
dkato 1:fdd79b99ba73 139 p_buf[i] = 0;
dkato 1:fdd79b99ba73 140 }
dkato 1:fdd79b99ba73 141
dkato 1:fdd79b99ba73 142 while (idx_w >= 0) {
dkato 1:fdd79b99ba73 143 // padding
dkato 1:fdd79b99ba73 144 for (i = 0; i < padding_size; i++) {
dkato 1:fdd79b99ba73 145 p_buf[idx_w--] = 0x00;
dkato 1:fdd79b99ba73 146 }
dkato 1:fdd79b99ba73 147 for (i = 0; i < block_byte; i++) {
dkato 1:fdd79b99ba73 148 p_buf[idx_w--] = p_buf[idx_r--];
dkato 1:fdd79b99ba73 149 }
dkato 1:fdd79b99ba73 150 }
dkato 1:fdd79b99ba73 151 dcache_clean(p_buf, _audio_buff_size);
dkato 1:fdd79b99ba73 152 _audio->write(p_buf, _audio_buff_size, &audio_write_async_ctl);
dkato 1:fdd79b99ba73 153 } else {
dkato 1:fdd79b99ba73 154 dcache_clean(p_buf, audio_data_size);
dkato 1:fdd79b99ba73 155 _audio->write(p_buf, audio_data_size, &audio_write_async_ctl);
dkato 1:fdd79b99ba73 156 }
dkato 0:9956e2ed09da 157 _buff_index = (_buff_index + 1) & AUDIO_MSK_RING_BUFF;
dkato 1:fdd79b99ba73 158 } else {
dkato 1:fdd79b99ba73 159 break;
dkato 0:9956e2ed09da 160 }
dkato 0:9956e2ed09da 161 }
dkato 0:9956e2ed09da 162 Thread::wait(500);
dkato 0:9956e2ed09da 163 ret = true;
dkato 0:9956e2ed09da 164 }
dkato 0:9956e2ed09da 165 delete decoder;
dkato 1:fdd79b99ba73 166 if (fp != NULL) {
dkato 1:fdd79b99ba73 167 fclose(fp);
dkato 1:fdd79b99ba73 168 }
dkato 0:9956e2ed09da 169
dkato 0:9956e2ed09da 170 return ret;
dkato 0:9956e2ed09da 171 }
dkato 0:9956e2ed09da 172
dkato 0:9956e2ed09da 173 bool EasyPlayback::is_paused(void)
dkato 0:9956e2ed09da 174 {
dkato 0:9956e2ed09da 175 return _pause;
dkato 0:9956e2ed09da 176 }
dkato 0:9956e2ed09da 177
dkato 0:9956e2ed09da 178 void EasyPlayback::pause()
dkato 0:9956e2ed09da 179 {
dkato 0:9956e2ed09da 180 _pause = !_pause;
dkato 0:9956e2ed09da 181 }
dkato 0:9956e2ed09da 182
dkato 0:9956e2ed09da 183 void EasyPlayback::pause(bool type)
dkato 0:9956e2ed09da 184 {
dkato 0:9956e2ed09da 185 _pause = type;
dkato 0:9956e2ed09da 186 }
dkato 0:9956e2ed09da 187
dkato 0:9956e2ed09da 188 void EasyPlayback::skip(void)
dkato 0:9956e2ed09da 189 {
dkato 0:9956e2ed09da 190 _skip = true;
dkato 0:9956e2ed09da 191 }
dkato 0:9956e2ed09da 192
dkato 0:9956e2ed09da 193 bool EasyPlayback::outputVolume(float VolumeOut)
dkato 0:9956e2ed09da 194 {
dkato 0:9956e2ed09da 195 if (!_init_end) {
dkato 1:fdd79b99ba73 196 _audio->power();
dkato 0:9956e2ed09da 197 _init_end = true;
dkato 0:9956e2ed09da 198 }
dkato 1:fdd79b99ba73 199 return _audio->outputVolume(VolumeOut, VolumeOut);
dkato 0:9956e2ed09da 200 }
dkato 0:9956e2ed09da 201
dkato 0:9956e2ed09da 202 EasyDecoder * EasyPlayback::create_decoer_class(const char* filename)
dkato 0:9956e2ed09da 203 {
dkato 0:9956e2ed09da 204 std::map<std::string, EasyDecoder*(*)()>::iterator itr;
dkato 0:9956e2ed09da 205 char *extension = strstr((char *)filename, ".");
dkato 0:9956e2ed09da 206
dkato 0:9956e2ed09da 207 if (extension == NULL) {
dkato 0:9956e2ed09da 208 return NULL;
dkato 0:9956e2ed09da 209 }
dkato 0:9956e2ed09da 210
dkato 0:9956e2ed09da 211 itr = m_lpDecoders.find(extension);
dkato 0:9956e2ed09da 212 if (itr == m_lpDecoders.end()) {
dkato 0:9956e2ed09da 213 return NULL;
dkato 0:9956e2ed09da 214 }
dkato 0:9956e2ed09da 215
dkato 0:9956e2ed09da 216 return (*itr).second();
dkato 0:9956e2ed09da 217 }
dkato 0:9956e2ed09da 218