Daiki Kato / EasyPlayback

Dependents:   GR-PEACH_Audio_WAV_PwmOut GR-Boards_Audio_WAV

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyDec_Mov.cpp Source File

EasyDec_Mov.cpp

00001 /* mbed EasyDec_Mov Library
00002  * Copyright (C) 2018 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 "EasyDec_Mov.h"
00018 
00019 #define FourConstant(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
00020 
00021 #ifndef htonl
00022 #   define htonl(x) __REV(x)
00023 #endif
00024 #ifndef ntohl
00025 #   define ntohl(x) __REV(x)
00026 #endif
00027 
00028 uint8_t * EasyDec_Mov::_videoBuf = NULL;
00029 uint32_t EasyDec_Mov::_videoBufSize = 0;
00030 Callback<void()> EasyDec_Mov::_function = NULL;
00031 
00032 void EasyDec_Mov::attach(Callback<void()> func, uint8_t * video_buf, uint32_t video_buf_size) {
00033     _function = func;
00034     _videoBuf = video_buf;
00035     _videoBufSize = video_buf_size;
00036 }
00037 
00038 bool EasyDec_Mov::AnalyzeHeder(char* p_title, char* p_artist, char* p_album, uint16_t tag_size, FILE* fp) {
00039     Buffer buf;
00040 
00041     if (fp == NULL) {
00042         return false;
00043     }
00044     if (p_title != NULL) {
00045         p_title[0] = '\0';
00046     }
00047     if (p_artist != NULL) {
00048         p_artist[0] = '\0';
00049     }
00050     if (p_album != NULL) {
00051         p_album[0] = '\0';
00052     }
00053 
00054     mov_fp = fp;
00055     availableCount = bufSize;
00056 
00057     frameSizesP = frameSizes;
00058     audioSizesP = audioSizes;
00059 
00060     search(htonl(FourConstant('s', 't', 's', 'z')));
00061     fseek(mov_fp, 8, SEEK_CUR);
00062     fread(&buf, sizeof(Buffer), 1, mov_fp);
00063     numOfFrames = htonl(buf.value);
00064     stszAddress = ftell(mov_fp);
00065     fread(&buf, sizeof(Buffer), 1, mov_fp);
00066 
00067     search(htonl(FourConstant('s', 't', 'c', 'o')));
00068     fseek(mov_fp, 4, SEEK_CUR);
00069     fread(&buf, sizeof(Buffer), 1, mov_fp);
00070     if (numOfFrames != htonl(buf.value)) {
00071         return false;
00072     }
00073     fread(&buf, sizeof(Buffer), 1, mov_fp);
00074     stcoAddress = ftell(mov_fp);
00075     lastFrameAddress = htonl(buf.value);
00076 
00077     fillCaches();
00078 
00079     _video_flg = true;
00080 
00081     return true;
00082 }
00083 
00084 size_t EasyDec_Mov::GetNextData(void *buf, size_t len) {
00085     size_t ret;
00086     uint32_t rest_size = 0;
00087     uint32_t aSize = *audioSizesP;
00088 
00089     if (numOfFrames <= 0) {
00090         return 0;
00091     }
00092 
00093     if (_video_flg) {
00094         _video_flg = false;
00095         if ((_videoBuf == NULL) || (*frameSizesP > _videoBufSize)) {
00096             fseek(mov_fp, *frameSizesP, SEEK_CUR);
00097         } else {
00098             fread(_videoBuf, 1, *frameSizesP, mov_fp);
00099             if (_function) {
00100                 _function();
00101             }
00102         }
00103         frameSizesP++;
00104     }
00105 
00106     if ((int)aSize < 0) {
00107         ret = 0;
00108     } else {
00109         if (aSize > len) {
00110             rest_size = aSize - len;
00111             *audioSizesP = rest_size;
00112             aSize = len;
00113         }
00114         ret = (uint32_t)fread(buf, 1, aSize, mov_fp);
00115     }
00116     if (rest_size == 0) {
00117         _video_flg = true;
00118         audioSizesP++;
00119         if (--availableCount == 0) {
00120             fillCaches();
00121         }
00122         numOfFrames--;
00123     }
00124 
00125     return ret;
00126 }
00127 
00128 uint16_t EasyDec_Mov::GetChannel() {
00129     return 2;
00130 }
00131 
00132 uint16_t EasyDec_Mov::GetBlockSize() {
00133     return 16;
00134 }
00135 
00136 uint32_t EasyDec_Mov::GetSamplingRate() {
00137     return 44100;
00138 }
00139 
00140 void EasyDec_Mov::search(uint32_t pattern) {
00141     Buffer buf;
00142     uint8_t first = pattern & 0xFF;
00143     buf.value = 0;
00144     while (true) {
00145         size_t size = fread(buf.array, sizeof(int8_t), 1, mov_fp);
00146         if (size == 0) {
00147             return;
00148         }
00149         if (buf.array[0] == first) {
00150             fread(&buf.array[1], sizeof(int8_t), 3, mov_fp);
00151             if (buf.value == pattern) {
00152                 break;
00153             }
00154         }
00155     }
00156 }
00157 
00158 void EasyDec_Mov::fillCaches() {
00159     Buffer buf[bufSize];
00160     Buffer *bufP = buf;
00161     uint32_t lastFrame = lastFrameAddress;
00162 
00163     fseek(mov_fp, stszAddress, SEEK_SET);
00164     fread(frameSizes, sizeof(uint32_t), bufSize, mov_fp);
00165     stszAddress += sizeof(uint32_t) * bufSize;
00166 
00167     fseek(mov_fp, stcoAddress, SEEK_SET);
00168     stcoAddress += sizeof(uint32_t) * bufSize;
00169     fread(buf, sizeof(Buffer), bufSize, mov_fp);
00170     availableCount = bufSize;
00171     frameSizesP = frameSizes;
00172     audioSizesP = audioSizes;
00173     do {
00174         uint32_t frameAddress = htonl(bufP->value);
00175         *frameSizesP = htonl(*frameSizesP);
00176         *audioSizesP++ = frameAddress - lastFrameAddress - *frameSizesP;
00177         lastFrameAddress = frameAddress;
00178         ++frameSizesP;
00179         ++bufP;
00180     } while (--availableCount);
00181 
00182     fseek(mov_fp, lastFrame, SEEK_SET);
00183     availableCount = bufSize;
00184     frameSizesP = frameSizes;
00185     audioSizesP = audioSizes;
00186 }
00187 
00188