test public

Dependencies:   HttpServer_snapshot_mbed-os

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyPlayback.cpp Source File

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_buff_size = 0;
00025     _audio_write_buff_num = 0;
00026     _audio_ssif = NULL;
00027     _audio_pwm = NULL;
00028 #if (R_BSP_SPDIF_ENABLE == 1)
00029     _audio_spdif = NULL;
00030 #endif
00031     _audio_soundless = NULL;
00032     _heap_buf = NULL;
00033     _audio_buf = NULL;
00034     if (_type == AUDIO_TPYE_SSIF) {
00035         _audio_buff_size = 4096;
00036         _audio_write_buff_num = 8;
00037         _audio_ssif = new AUDIO_GRBoard(0x80, (_audio_write_buff_num - 1), 0);
00038         _audio = _audio_ssif;
00039     } else if (_type == AUDIO_TPYE_PWM) {
00040         _audio_buff_size = 4096;
00041         _audio_write_buff_num = 8;
00042         _audio_pwm = new PwmOutSpeaker(pin1, pin2);
00043         _audio = _audio_pwm;
00044     } else if (_type == AUDIO_TPYE_SPDIF) {
00045 #if (R_BSP_SPDIF_ENABLE == 1)
00046         _audio_buff_size = (192 * 2 * 10);
00047         _audio_write_buff_num = 8;
00048         _audio_spdif = new SPDIF_GRBoard(0x80, (_audio_write_buff_num - 1), 0);
00049         _audio = _audio_spdif;
00050 #else
00051         MBED_ASSERT(false);
00052 #endif
00053     } else if (_type == AUDIO_TPYE_SOUNDLESS) {
00054         _audio_buff_size = (4410 * 2);
00055         _audio_write_buff_num = 0;
00056         _audio_soundless = new SoundlessSpeaker();
00057         _audio = _audio_soundless;
00058     } else if (_type == AUDIO_TPYE_NULL) {
00059         _audio_buff_size = 4096;
00060         _audio_write_buff_num = 0;
00061         _audio_null = new NullSpeaker();
00062         _audio = _audio_null;
00063     } else {
00064         MBED_ASSERT(false);
00065     }
00066     if ((_audio_buff_size != 0) && (_audio_write_buff_num != 0)) {
00067         _heap_buf = new uint8_t[_audio_buff_size * _audio_write_buff_num + 31];
00068         _audio_buf = (uint8_t *)(((uint32_t)_heap_buf + 31ul) & ~31ul);
00069     }
00070 }
00071 
00072 EasyPlayback::~EasyPlayback()
00073 {
00074     if (_audio_ssif != NULL) {
00075         delete _audio_ssif;
00076     }
00077     if (_audio_pwm != NULL) {
00078         delete _audio_pwm;
00079     }
00080 #if (R_BSP_SPDIF_ENABLE == 1)
00081     if (_audio_spdif != NULL) {
00082         delete _audio_spdif;
00083     }
00084 #endif
00085     if (_audio_soundless != NULL) {
00086         delete _audio_soundless;
00087     }
00088     if (_heap_buf != NULL) {
00089         delete [] _heap_buf;
00090     }
00091 }
00092 
00093 bool EasyPlayback::get_tag(const char* filename, char* p_title, char* p_artist, char* p_album, uint16_t tag_size)
00094 {
00095     FILE * fp = NULL;
00096     EasyDecoder * decoder;
00097     bool ret = false;
00098 
00099     decoder = create_decoer_class(filename);
00100     if (decoder == NULL) {
00101         return false;
00102     }
00103 
00104     fp = fopen(filename, "r");
00105     if (fp == NULL) {
00106         // do nothing
00107     } else if (decoder->AnalyzeHeder(p_title, p_artist, p_album, tag_size, fp) != false) {
00108         ret = true;
00109     }
00110     delete decoder;
00111     if (fp != NULL) {
00112         fclose(fp);
00113     }
00114 
00115     return ret;
00116 }
00117 
00118 bool EasyPlayback::play(const char* filename)
00119 {
00120     const rbsp_data_conf_t audio_write_async_ctl = {NULL, NULL};
00121     size_t audio_data_size;
00122     FILE * fp = NULL;
00123     uint8_t * p_buf;
00124     uint32_t read_size;
00125     uint32_t i;
00126     EasyDecoder * decoder;
00127     bool ret = false;
00128     uint32_t padding_size;
00129 
00130     decoder = create_decoer_class(filename);
00131     if (decoder == NULL) {
00132         return false;
00133     }
00134 
00135     if (!_init_end) {
00136         _audio->power();
00137         _audio->outputVolume(1.0, 1.0);
00138         _init_end = true;
00139     }
00140 
00141      _skip = false;
00142     fp = fopen(filename, "r");
00143     if (fp == NULL) {
00144         // do nothing
00145     } else if (decoder->AnalyzeHeder(NULL, NULL, NULL, 0, fp) == false) {
00146         // do nothing
00147     } else if  ((decoder->GetChannel() != 2)
00148             || (_audio->format(decoder->GetBlockSize()) == false)
00149             || (_audio->frequency(decoder->GetSamplingRate()) == false)) {
00150         // do nothing
00151     } else {
00152         if ((_type == AUDIO_TPYE_SPDIF) && (decoder->GetBlockSize() == 16)) {
00153             padding_size = 2;
00154             read_size = _audio_buff_size / 2;
00155         } else if ((decoder->GetBlockSize() == 20) || (decoder->GetBlockSize() == 24)) {
00156             padding_size = 1;
00157             read_size = _audio_buff_size * 3 / 4;
00158         } else {
00159             padding_size = 0;
00160             read_size = _audio_buff_size;
00161         }
00162         setvbuf(fp, NULL, _IONBF, 0); // unbuffered
00163 
00164         while (true) {
00165             while ((_pause) && (!_skip)) {
00166                 ThisThread::sleep_for(100);
00167             }
00168             if (_skip) {
00169                 break;
00170             }
00171             if (_audio_buf == NULL) {
00172                 audio_data_size = decoder->GetNextData(NULL, read_size);
00173                 if (audio_data_size > 0) {
00174                     if (padding_size != 0) {
00175                         _audio->write(NULL, _audio_buff_size, &audio_write_async_ctl);
00176                     } else {
00177                         _audio->write(NULL, audio_data_size, &audio_write_async_ctl);
00178                     }
00179                 } else {
00180                     break;
00181                 }
00182             } else {
00183                 p_buf = &_audio_buf[_audio_buff_size * _buff_index];
00184                 audio_data_size = decoder->GetNextData(p_buf, read_size);
00185                 if (audio_data_size > 0) {
00186                     if (padding_size != 0) {
00187                         int idx_w = _audio_buff_size - 1;
00188                         int idx_r = read_size - 1;
00189                         uint32_t block_byte = (decoder->GetBlockSize() + 7) / 8;
00190 
00191                         // fill the shortfall with 0
00192                         for (i = audio_data_size; i < read_size; i++) {
00193                             p_buf[i] = 0;
00194                         }
00195 
00196                         while (idx_w >= 0) {
00197                             // padding
00198                             for (i = 0; i < padding_size; i++) {
00199                                 p_buf[idx_w--] = 0x00;
00200                             }
00201                             for (i = 0; i < block_byte; i++) {
00202                                 p_buf[idx_w--] = p_buf[idx_r--];
00203                             }
00204                         }
00205                         dcache_clean(p_buf, _audio_buff_size);
00206                         _audio->write(p_buf, _audio_buff_size, &audio_write_async_ctl);
00207                     } else {
00208                         dcache_clean(p_buf, audio_data_size);
00209                         _audio->write(p_buf, audio_data_size, &audio_write_async_ctl);
00210                     }
00211                     if ((_buff_index + 1) < _audio_write_buff_num) {
00212                         _buff_index++;
00213                     } else {
00214                         _buff_index = 0;
00215                     }
00216                 } else {
00217                     break;
00218                 }
00219             }
00220         }
00221         ThisThread::sleep_for(500);
00222         ret = true;
00223     }
00224     delete decoder;
00225     if (fp != NULL) {
00226         fclose(fp);
00227     }
00228 
00229     return ret;
00230 }
00231 
00232 bool EasyPlayback::is_paused(void)
00233 {
00234     return _pause;
00235 }
00236 
00237 void EasyPlayback::pause()
00238 {
00239     _pause = !_pause;
00240 }
00241 
00242 void EasyPlayback::pause(bool type)
00243 {
00244     _pause = type;
00245 }
00246 
00247 void EasyPlayback::skip(void)
00248 {
00249     _skip = true;
00250 }
00251 
00252 bool EasyPlayback::outputVolume(float VolumeOut)
00253 {
00254     if (!_init_end) {
00255         _audio->power();
00256         _init_end = true;
00257     }
00258     return _audio->outputVolume(VolumeOut, VolumeOut);
00259 }
00260 
00261 EasyDecoder * EasyPlayback::create_decoer_class(const char* filename)
00262 {
00263     std::map<std::string, EasyDecoder*(*)()>::iterator itr;
00264     char *extension = strstr((char *)filename, ".");
00265 
00266     if (extension == NULL) {
00267         return NULL;
00268     }
00269 
00270     itr = m_lpDecoders.find(extension);
00271     if (itr == m_lpDecoders.end()) {
00272         return NULL;
00273     }
00274 
00275     return (*itr).second();
00276 }
00277