Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GR-PEACH_Audio_WAV_PwmOut GR-Boards_Audio_WAV
EasyPlayback.cpp
00001 /* mbed EasyPlayback Library 00002 * Copyright (C) 2017 dkato 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "dcache-control.h" 00019 #include "EasyPlayback.h" 00020 00021 EasyPlayback::EasyPlayback(audio_type_t type, PinName pin1, PinName pin2) : 00022 _buff_index(0), _type(type), _skip(false), _pause(false), _init_end(false) 00023 { 00024 _audio_ssif = NULL; 00025 _audio_pwm = NULL; 00026 if (_type == AUDIO_TPYE_SSIF) { 00027 _audio_buff_size = 4096; 00028 _audio_ssif = new AUDIO_GRBoard(0x80, (AUDIO_WRITE_BUFF_NUM - 1), 0); 00029 _audio = _audio_ssif; 00030 } else if (_type == AUDIO_TPYE_PWM) { 00031 _audio_buff_size = 4096; 00032 _audio_pwm = new PwmOutSpeaker(pin1, pin2); 00033 _audio = _audio_pwm; 00034 } else if (_type == AUDIO_TPYE_SPDIF) { 00035 MBED_ASSERT(false); 00036 } else { 00037 MBED_ASSERT(false); 00038 } 00039 _heap_buf = new uint8_t[_audio_buff_size * AUDIO_WRITE_BUFF_NUM + 31]; 00040 _audio_buf = (uint8_t *)(((uint32_t)_heap_buf + 31ul) & ~31ul); 00041 } 00042 00043 EasyPlayback::~EasyPlayback() 00044 { 00045 if (_audio_ssif != NULL) { 00046 delete _audio_ssif; 00047 } 00048 if (_audio_pwm != NULL) { 00049 delete _audio_pwm; 00050 } 00051 delete [] _heap_buf; 00052 } 00053 00054 bool EasyPlayback::get_tag(const char* filename, char* p_title, char* p_artist, char* p_album, uint16_t tag_size) 00055 { 00056 FILE * fp = NULL; 00057 EasyDecoder * decoder; 00058 bool ret = false; 00059 00060 decoder = create_decoer_class(filename); 00061 if (decoder == NULL) { 00062 return false; 00063 } 00064 00065 fp = fopen(filename, "r"); 00066 if (fp == NULL) { 00067 // do nothing 00068 } else if (decoder->AnalyzeHeder(p_title, p_artist, p_album, tag_size, fp) != false) { 00069 ret = true; 00070 } 00071 delete decoder; 00072 if (fp != NULL) { 00073 fclose(fp); 00074 } 00075 00076 return ret; 00077 } 00078 00079 bool EasyPlayback::play(const char* filename) 00080 { 00081 const rbsp_data_conf_t audio_write_async_ctl = {NULL, NULL}; 00082 size_t audio_data_size; 00083 FILE * fp = NULL; 00084 uint8_t * p_buf; 00085 uint32_t read_size; 00086 uint32_t i; 00087 EasyDecoder * decoder; 00088 bool ret = false; 00089 uint32_t padding_size; 00090 00091 decoder = create_decoer_class(filename); 00092 if (decoder == NULL) { 00093 return false; 00094 } 00095 00096 if (!_init_end) { 00097 _audio->power(); 00098 _audio->outputVolume(1.0, 1.0); 00099 _init_end = true; 00100 } 00101 00102 _skip = false; 00103 fp = fopen(filename, "r"); 00104 if (fp == NULL) { 00105 // do nothing 00106 } else if (decoder->AnalyzeHeder(NULL, NULL, NULL, 0, fp) == false) { 00107 // do nothing 00108 } else if ((decoder->GetChannel() != 2) 00109 || (_audio->format(decoder->GetBlockSize()) == false) 00110 || (_audio->frequency(decoder->GetSamplingRate()) == false)) { 00111 // do nothing 00112 } else { 00113 if ((_type == AUDIO_TPYE_SPDIF) && (decoder->GetBlockSize() == 16)) { 00114 padding_size = 2; 00115 read_size = _audio_buff_size / 2; 00116 } else if ((decoder->GetBlockSize() == 20) || (decoder->GetBlockSize() == 24)) { 00117 padding_size = 1; 00118 read_size = _audio_buff_size * 3 / 4; 00119 } else { 00120 padding_size = 0; 00121 read_size = _audio_buff_size; 00122 } 00123 setvbuf(fp, NULL, _IONBF, 0); // unbuffered 00124 00125 while (true) { 00126 while ((_pause) && (!_skip)) { 00127 Thread::wait(100); 00128 } 00129 if (_skip) { 00130 break; 00131 } 00132 p_buf = &_audio_buf[_audio_buff_size * _buff_index]; 00133 audio_data_size = decoder->GetNextData(p_buf, read_size); 00134 if (audio_data_size > 0) { 00135 if (padding_size != 0) { 00136 int idx_w = _audio_buff_size - 1; 00137 int idx_r = read_size - 1; 00138 uint32_t block_byte = (decoder->GetBlockSize() + 7) / 8; 00139 00140 // fill the shortfall with 0 00141 for (i = audio_data_size; i < read_size; i++) { 00142 p_buf[i] = 0; 00143 } 00144 00145 while (idx_w >= 0) { 00146 // padding 00147 for (i = 0; i < padding_size; i++) { 00148 p_buf[idx_w--] = 0x00; 00149 } 00150 for (i = 0; i < block_byte; i++) { 00151 p_buf[idx_w--] = p_buf[idx_r--]; 00152 } 00153 } 00154 dcache_clean(p_buf, _audio_buff_size); 00155 _audio->write(p_buf, _audio_buff_size, &audio_write_async_ctl); 00156 } else { 00157 dcache_clean(p_buf, audio_data_size); 00158 _audio->write(p_buf, audio_data_size, &audio_write_async_ctl); 00159 } 00160 _buff_index = (_buff_index + 1) & AUDIO_MSK_RING_BUFF; 00161 } else { 00162 break; 00163 } 00164 } 00165 Thread::wait(500); 00166 ret = true; 00167 } 00168 delete decoder; 00169 if (fp != NULL) { 00170 fclose(fp); 00171 } 00172 00173 return ret; 00174 } 00175 00176 bool EasyPlayback::is_paused(void) 00177 { 00178 return _pause; 00179 } 00180 00181 void EasyPlayback::pause() 00182 { 00183 _pause = !_pause; 00184 } 00185 00186 void EasyPlayback::pause(bool type) 00187 { 00188 _pause = type; 00189 } 00190 00191 void EasyPlayback::skip(void) 00192 { 00193 _skip = true; 00194 } 00195 00196 bool EasyPlayback::outputVolume(float VolumeOut) 00197 { 00198 if (!_init_end) { 00199 _audio->power(); 00200 _init_end = true; 00201 } 00202 return _audio->outputVolume(VolumeOut, VolumeOut); 00203 } 00204 00205 EasyDecoder * EasyPlayback::create_decoer_class(const char* filename) 00206 { 00207 std::map<std::string, EasyDecoder*(*)()>::iterator itr; 00208 char *extension = strstr((char *)filename, "."); 00209 00210 if (extension == NULL) { 00211 return NULL; 00212 } 00213 00214 itr = m_lpDecoders.find(extension); 00215 if (itr == m_lpDecoders.end()) { 00216 return NULL; 00217 } 00218 00219 return (*itr).second(); 00220 } 00221
Generated on Tue Jul 12 2022 18:37:53 by
1.7.2