test public

Dependencies:   HttpServer_snapshot_mbed-os

Committer:
anhtran
Date:
Fri Oct 18 03:09:43 2019 +0000
Revision:
0:e9fd5575b10e
abc

Who changed what in which revision?

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