yoshi matsu / EasyPlayback
Committer:
matsumatsu
Date:
Mon Dec 10 06:33:17 2018 +0000
Revision:
3:788e909d7a08
Parent:
2:6c46c61630b3
test

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
matsumatsu 3:788e909d7a08 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 } else if (_type == AUDIO_TPYE_SPDIF) {
dkato 1:fdd79b99ba73 29 MBED_ASSERT(false);
dkato 1:fdd79b99ba73 30 } else {
dkato 1:fdd79b99ba73 31 MBED_ASSERT(false);
dkato 1:fdd79b99ba73 32 }
dkato 1:fdd79b99ba73 33 _heap_buf = new uint8_t[_audio_buff_size * AUDIO_WRITE_BUFF_NUM + 31];
dkato 1:fdd79b99ba73 34 _audio_buf = (uint8_t *)(((uint32_t)_heap_buf + 31ul) & ~31ul);
dkato 0:9956e2ed09da 35 }
dkato 0:9956e2ed09da 36
dkato 0:9956e2ed09da 37 EasyPlayback::~EasyPlayback()
dkato 0:9956e2ed09da 38 {
dkato 1:fdd79b99ba73 39 if (_audio_ssif != NULL) {
dkato 1:fdd79b99ba73 40 delete _audio_ssif;
dkato 1:fdd79b99ba73 41 }
matsumatsu 3:788e909d7a08 42 #if (R_BSP_SPDIF_ENABLE == 1)
matsumatsu 3:788e909d7a08 43 if (_audio_spdif != NULL) {
matsumatsu 3:788e909d7a08 44 delete _audio_spdif;
dkato 1:fdd79b99ba73 45 }
matsumatsu 3:788e909d7a08 46 #endif
dkato 0:9956e2ed09da 47 delete [] _heap_buf;
dkato 0:9956e2ed09da 48 }
dkato 0:9956e2ed09da 49
dkato 0:9956e2ed09da 50 bool EasyPlayback::get_tag(const char* filename, char* p_title, char* p_artist, char* p_album, uint16_t tag_size)
dkato 0:9956e2ed09da 51 {
dkato 1:fdd79b99ba73 52 FILE * fp = NULL;
dkato 0:9956e2ed09da 53 EasyDecoder * decoder;
dkato 0:9956e2ed09da 54 bool ret = false;
dkato 0:9956e2ed09da 55
dkato 0:9956e2ed09da 56 decoder = create_decoer_class(filename);
dkato 0:9956e2ed09da 57 if (decoder == NULL) {
dkato 0:9956e2ed09da 58 return false;
dkato 0:9956e2ed09da 59 }
dkato 0:9956e2ed09da 60
dkato 0:9956e2ed09da 61 fp = fopen(filename, "r");
dkato 1:fdd79b99ba73 62 if (fp == NULL) {
dkato 1:fdd79b99ba73 63 // do nothing
dkato 1:fdd79b99ba73 64 } else if (decoder->AnalyzeHeder(p_title, p_artist, p_album, tag_size, fp) != false) {
dkato 0:9956e2ed09da 65 ret = true;
dkato 0:9956e2ed09da 66 }
dkato 0:9956e2ed09da 67 delete decoder;
dkato 1:fdd79b99ba73 68 if (fp != NULL) {
dkato 1:fdd79b99ba73 69 fclose(fp);
dkato 1:fdd79b99ba73 70 }
dkato 0:9956e2ed09da 71
dkato 0:9956e2ed09da 72 return ret;
dkato 0:9956e2ed09da 73 }
dkato 0:9956e2ed09da 74
dkato 0:9956e2ed09da 75 bool EasyPlayback::play(const char* filename)
dkato 0:9956e2ed09da 76 {
dkato 0:9956e2ed09da 77 const rbsp_data_conf_t audio_write_async_ctl = {NULL, NULL};
dkato 1:fdd79b99ba73 78 size_t audio_data_size;
dkato 1:fdd79b99ba73 79 FILE * fp = NULL;
dkato 0:9956e2ed09da 80 uint8_t * p_buf;
dkato 1:fdd79b99ba73 81 uint32_t read_size;
dkato 1:fdd79b99ba73 82 uint32_t i;
dkato 0:9956e2ed09da 83 EasyDecoder * decoder;
dkato 0:9956e2ed09da 84 bool ret = false;
dkato 1:fdd79b99ba73 85 uint32_t padding_size;
dkato 0:9956e2ed09da 86
dkato 0:9956e2ed09da 87 decoder = create_decoer_class(filename);
dkato 0:9956e2ed09da 88 if (decoder == NULL) {
dkato 0:9956e2ed09da 89 return false;
dkato 0:9956e2ed09da 90 }
dkato 0:9956e2ed09da 91
dkato 0:9956e2ed09da 92 if (!_init_end) {
matsumatsu 3:788e909d7a08 93 _audio_ssif->power();
matsumatsu 3:788e909d7a08 94 _audio_ssif->outputVolume(1.0, 1.0);
dkato 0:9956e2ed09da 95 _init_end = true;
dkato 0:9956e2ed09da 96 }
dkato 0:9956e2ed09da 97
dkato 0:9956e2ed09da 98 _skip = false;
dkato 0:9956e2ed09da 99 fp = fopen(filename, "r");
dkato 1:fdd79b99ba73 100 if (fp == NULL) {
dkato 1:fdd79b99ba73 101 // do nothing
dkato 1:fdd79b99ba73 102 } else if (decoder->AnalyzeHeder(NULL, NULL, NULL, 0, fp) == false) {
dkato 0:9956e2ed09da 103 // do nothing
dkato 0:9956e2ed09da 104 } else if ((decoder->GetChannel() != 2)
dkato 1:fdd79b99ba73 105 || (_audio->format(decoder->GetBlockSize()) == false)
dkato 1:fdd79b99ba73 106 || (_audio->frequency(decoder->GetSamplingRate()) == false)) {
dkato 0:9956e2ed09da 107 // do nothing
dkato 0:9956e2ed09da 108 } else {
dkato 1:fdd79b99ba73 109 if ((_type == AUDIO_TPYE_SPDIF) && (decoder->GetBlockSize() == 16)) {
dkato 1:fdd79b99ba73 110 padding_size = 2;
dkato 1:fdd79b99ba73 111 read_size = _audio_buff_size / 2;
dkato 1:fdd79b99ba73 112 } else if ((decoder->GetBlockSize() == 20) || (decoder->GetBlockSize() == 24)) {
dkato 1:fdd79b99ba73 113 padding_size = 1;
dkato 1:fdd79b99ba73 114 read_size = _audio_buff_size * 3 / 4;
dkato 1:fdd79b99ba73 115 } else {
dkato 1:fdd79b99ba73 116 padding_size = 0;
dkato 1:fdd79b99ba73 117 read_size = _audio_buff_size;
dkato 1:fdd79b99ba73 118 }
dkato 1:fdd79b99ba73 119 setvbuf(fp, NULL, _IONBF, 0); // unbuffered
dkato 1:fdd79b99ba73 120
dkato 1:fdd79b99ba73 121 while (true) {
dkato 0:9956e2ed09da 122 while ((_pause) && (!_skip)) {
dkato 0:9956e2ed09da 123 Thread::wait(100);
dkato 0:9956e2ed09da 124 }
dkato 0:9956e2ed09da 125 if (_skip) {
dkato 0:9956e2ed09da 126 break;
dkato 0:9956e2ed09da 127 }
dkato 1:fdd79b99ba73 128 p_buf = &_audio_buf[_audio_buff_size * _buff_index];
dkato 1:fdd79b99ba73 129 audio_data_size = decoder->GetNextData(p_buf, read_size);
dkato 0:9956e2ed09da 130 if (audio_data_size > 0) {
dkato 1:fdd79b99ba73 131 if (padding_size != 0) {
dkato 1:fdd79b99ba73 132 int idx_w = _audio_buff_size - 1;
dkato 1:fdd79b99ba73 133 int idx_r = read_size - 1;
dkato 1:fdd79b99ba73 134 uint32_t block_byte = (decoder->GetBlockSize() + 7) / 8;
dkato 1:fdd79b99ba73 135
dkato 1:fdd79b99ba73 136 // fill the shortfall with 0
dkato 1:fdd79b99ba73 137 for (i = audio_data_size; i < read_size; i++) {
dkato 1:fdd79b99ba73 138 p_buf[i] = 0;
dkato 1:fdd79b99ba73 139 }
dkato 1:fdd79b99ba73 140
dkato 1:fdd79b99ba73 141 while (idx_w >= 0) {
dkato 1:fdd79b99ba73 142 // padding
dkato 1:fdd79b99ba73 143 for (i = 0; i < padding_size; i++) {
dkato 1:fdd79b99ba73 144 p_buf[idx_w--] = 0x00;
dkato 1:fdd79b99ba73 145 }
dkato 1:fdd79b99ba73 146 for (i = 0; i < block_byte; i++) {
dkato 1:fdd79b99ba73 147 p_buf[idx_w--] = p_buf[idx_r--];
dkato 1:fdd79b99ba73 148 }
dkato 1:fdd79b99ba73 149 }
dkato 1:fdd79b99ba73 150 dcache_clean(p_buf, _audio_buff_size);
dkato 1:fdd79b99ba73 151 _audio->write(p_buf, _audio_buff_size, &audio_write_async_ctl);
dkato 1:fdd79b99ba73 152 } else {
dkato 1:fdd79b99ba73 153 dcache_clean(p_buf, audio_data_size);
dkato 1:fdd79b99ba73 154 _audio->write(p_buf, audio_data_size, &audio_write_async_ctl);
dkato 1:fdd79b99ba73 155 }
dkato 0:9956e2ed09da 156 _buff_index = (_buff_index + 1) & AUDIO_MSK_RING_BUFF;
dkato 1:fdd79b99ba73 157 } else {
dkato 1:fdd79b99ba73 158 break;
dkato 0:9956e2ed09da 159 }
dkato 0:9956e2ed09da 160 }
dkato 0:9956e2ed09da 161 Thread::wait(500);
dkato 0:9956e2ed09da 162 ret = true;
dkato 0:9956e2ed09da 163 }
dkato 0:9956e2ed09da 164 delete decoder;
dkato 1:fdd79b99ba73 165 if (fp != NULL) {
dkato 1:fdd79b99ba73 166 fclose(fp);
dkato 1:fdd79b99ba73 167 }
dkato 0:9956e2ed09da 168
dkato 0:9956e2ed09da 169 return ret;
dkato 0:9956e2ed09da 170 }
dkato 0:9956e2ed09da 171
dkato 0:9956e2ed09da 172 bool EasyPlayback::is_paused(void)
dkato 0:9956e2ed09da 173 {
dkato 0:9956e2ed09da 174 return _pause;
dkato 0:9956e2ed09da 175 }
dkato 0:9956e2ed09da 176
dkato 0:9956e2ed09da 177 void EasyPlayback::pause()
dkato 0:9956e2ed09da 178 {
dkato 0:9956e2ed09da 179 _pause = !_pause;
dkato 0:9956e2ed09da 180 }
dkato 0:9956e2ed09da 181
dkato 0:9956e2ed09da 182 void EasyPlayback::pause(bool type)
dkato 0:9956e2ed09da 183 {
dkato 0:9956e2ed09da 184 _pause = type;
dkato 0:9956e2ed09da 185 }
dkato 0:9956e2ed09da 186
dkato 0:9956e2ed09da 187 void EasyPlayback::skip(void)
dkato 0:9956e2ed09da 188 {
dkato 0:9956e2ed09da 189 _skip = true;
dkato 0:9956e2ed09da 190 }
dkato 0:9956e2ed09da 191
dkato 0:9956e2ed09da 192 bool EasyPlayback::outputVolume(float VolumeOut)
dkato 0:9956e2ed09da 193 {
dkato 0:9956e2ed09da 194 if (!_init_end) {
dkato 1:fdd79b99ba73 195 _audio->power();
dkato 0:9956e2ed09da 196 _init_end = true;
dkato 0:9956e2ed09da 197 }
dkato 1:fdd79b99ba73 198 return _audio->outputVolume(VolumeOut, VolumeOut);
dkato 0:9956e2ed09da 199 }
dkato 0:9956e2ed09da 200
dkato 0:9956e2ed09da 201 EasyDecoder * EasyPlayback::create_decoer_class(const char* filename)
dkato 0:9956e2ed09da 202 {
dkato 0:9956e2ed09da 203 std::map<std::string, EasyDecoder*(*)()>::iterator itr;
dkato 0:9956e2ed09da 204 char *extension = strstr((char *)filename, ".");
dkato 0:9956e2ed09da 205
dkato 0:9956e2ed09da 206 if (extension == NULL) {
dkato 0:9956e2ed09da 207 return NULL;
dkato 0:9956e2ed09da 208 }
dkato 0:9956e2ed09da 209
dkato 0:9956e2ed09da 210 itr = m_lpDecoders.find(extension);
dkato 0:9956e2ed09da 211 if (itr == m_lpDecoders.end()) {
dkato 0:9956e2ed09da 212 return NULL;
dkato 0:9956e2ed09da 213 }
dkato 0:9956e2ed09da 214
dkato 0:9956e2ed09da 215 return (*itr).second();
dkato 0:9956e2ed09da 216 }
dkato 0:9956e2ed09da 217