Music Player for ARCH-PRO
Dependencies: GT20L16J1Y_font TinyJpgDec mbed
GSDPlayer.cpp
00001 // -------------------------------------------------------- 00002 // GSDPlayer (c) CopYright 2013-2014 Goji. goji2100.com 00003 // -------------------------------------------------------- 00004 00005 #include "mbed.h" 00006 #include "mainconf.h" 00007 00008 #include "SDFileSystem.h" 00009 #include "TinyJpgDec.h" 00010 00011 #include "mGTFT.h" 00012 #include "mGTP.h" 00013 #include "GT20L16J1Y_font.h" 00014 00015 00016 /* SDFileSystem.cpp change 00017 ----------------------------------------------------------------------- 00018 144: _spi.frequency(16000000); 00019 210: _spi.frequency(24000000); // Set to 1MHz for data transfer 00020 */ 00021 00022 00023 //#define Level_Indicator 4000 // for Level Indicator 00024 //#define Test // for Simple Player 00025 00026 #define FILESYS "sd" 00027 #if defined(_ARCH_PRO) 00028 SDFileSystem sd(P0_9, P0_8, P0_7, P0_6, FILESYS); // Arch Pro SPI1SD 00029 #define BUFF_SIZE (512 * 4) // WAV file buffer size 00030 #define LLow 1 00031 #define LHigh 0 00032 PwmOut Line_R(P2_0), Line_L(P2_1); // PWM_1, PWM_2 00033 BusOut TFTBus(D8, D9, D2, D3, D4, D5, D6, D7); 00034 #else 00035 #endif 00036 00037 Serial pc(USBTX, USBRX); 00038 DigitalOut statLED1(LED1), statLED2(LED2), statLED3(LED3), statLED4(LED4); 00039 00040 #define PWM_CLKMHZ 24 // 24MHz 00041 Ticker Tick_Timer; 00042 00043 volatile uint16_t ps_stat = 0; // Player status 00044 uint16_t tp_stat = 0, tp_statN = 0; 00045 #define PS_PLAY BIT1(15) 00046 #define PS_PAUSE BIT1(14) 00047 #define PS_FFR BIT1(13) 00048 #define PS_FFF BIT1(12) 00049 #define PS_SEEK BIT1(11) 00050 #define PS_FR BIT1(10) 00051 #define PS_FF BIT1( 9) 00052 #define PS_VDOWN BIT1( 8) 00053 #define PS_VUP BIT1( 7) 00054 #define PS_EOR BIT1( 6) // End of Root 00055 #define PS_EOD BIT1( 5) // End of DIR 00056 #define PS_EOF BIT1( 4) // Eod of File 00057 00058 #define SWBuff() { if (buffNX==0) { buffNW=0,buffNX=1; } else { buffNW=1,buffNX=0; } buffLN[buffNX]=buffGP=0; } 00059 volatile int32_t buffNW, buffNX, buffLN[2], buffGP; 00060 unsigned char Wave_buff[2][BUFF_SIZE]; 00061 #define _WS16(n,v) *(short* )&Wave_buff[n][v] 00062 #define _WU16(n,v) *(unsigned short*)&Wave_buff[n][v] 00063 #define _WU32(n,v) *(unsigned long* )&Wave_buff[n][v] 00064 uint8_t Wave_CHs, Wave_Bits; 00065 uint32_t Wave_BPS, Wave_Size, Wave_Rlen, Wave_Play, Wave_FPos; 00066 uint16_t Wave_Prid; 00067 00068 volatile uint16_t Pwm_Ratio, Line_Vols = 16, Line_Vol = 160; 00069 00070 #if defined(Level_Indicator) 00071 volatile uint32_t Pwm_cnt = 0; 00072 volatile uint16_t Pwm_aveL = 0, Pwm_aveR = 0; 00073 #endif 00074 00075 void PwmLR_Out16(int16_t lv, int16_t rv) 00076 { 00077 int16_t lw = ((lv + 32768) / Pwm_Ratio); 00078 int16_t rw = ((rv + 32768) / Pwm_Ratio); 00079 // if (lw >= LPC_PWM1->MR0) lw = LPC_PWM1->MR0; 00080 // if (rw >= LPC_PWM1->MR0) rw = LPC_PWM1->MR0; 00081 #if defined(_ARCH_PRO) 00082 LPC_PWM1->MR1 = lw; 00083 LPC_PWM1->MR2 = rw; 00084 if (Line_Vols) 00085 LPC_PWM1->LER |= ((1 << 1) | (1 << 2)); 00086 #else 00087 LPC_PWM1->MR6 = lw; 00088 LPC_PWM1->MR5 = rw; 00089 if (Line_Vols) 00090 LPC_PWM1->LER |= ((1 << 6) | (1 << 5)); 00091 #endif 00092 #if defined(Level_Indicator) 00093 Pwm_cnt++; 00094 Pwm_aveL = (Pwm_aveL + ((uint16_t)(lv) + 32768) >> 8) / 2; 00095 Pwm_aveR = (Pwm_aveR + ((uint16_t)(rv) + 32768) >> 8) / 2; 00096 #endif 00097 } 00098 00099 00100 void ISR_Tick(void) 00101 { 00102 if (!(ps_stat & PS_PAUSE) && (buffGP < buffLN[buffNW])) { 00103 statLED2 = LHigh; 00104 PwmLR_Out16(_WS16(buffNW, buffGP), _WS16(buffNW, buffGP + 2)); 00105 buffGP += 4; 00106 if ((buffGP >= buffLN[buffNW]) && (buffNX != -1)) SWBuff(); 00107 statLED2 = LLow; 00108 } 00109 } 00110 00111 00112 extern TFT_INFO TFT_info; 00113 int32_t Last_Err; 00114 00115 GT20L16J1Y_FONT font(p11, p12, p13, P0_16); 00116 void draw_kanji(int x1, int y1, uint16_t c1, uint16_t c2) 00117 { 00118 for (int x = 0; x < 32; x++) 00119 for (int y = 0, m = 0x01; y < 8; y++, m <<= 1) 00120 TFT_setPixel(x1 + x%16, y1 + y + (8 * (x >> 4)), ((font.bitmap[x] & m) ? c1 : c2)); 00121 } 00122 00123 00124 uint16_t bmpXsize, bmpYsize; 00125 00126 void BMP24Bits(int16_t x1, int16_t y1, char *fn) 00127 { 00128 uint8_t rbuff[64]; 00129 00130 FILE *fp = fopen(fn, "rb"); 00131 if (!fp) { 00132 pc.printf("open error\n"); 00133 return; 00134 } 00135 00136 fread(rbuff, 1, (14 + 40), fp); 00137 bmpXsize = *(uint16_t*)&rbuff[18]; 00138 bmpYsize = *(uint16_t*)&rbuff[22]; 00139 00140 if ((bmpXsize > TFT_MAX_X) || 00141 (bmpYsize > TFT_MAX_Y) || 00142 (rbuff[28] != 24)) { 00143 pc.printf("format error\n"); 00144 return; 00145 } 00146 00147 int dummy = (bmpXsize * 3) % 4; 00148 for (int z = 0, y = y1; z < bmpYsize; z++, y--) { 00149 TFT_setXY(x1, y); 00150 for (int i = 0; i < bmpXsize; i++) { 00151 fread(rbuff, 1, 3, fp); 00152 TFT_wr_data((uint16_t)( 00153 ((rbuff[2] & 0xF8) << 8) | // R 00154 ((rbuff[1] & 0xFC) << 3) | // G 00155 ((rbuff[0] ) >> 3) )); // B 00156 } 00157 if (dummy) fread(rbuff, 1, dummy, fp); 00158 } 00159 fclose(fp); 00160 } 00161 00162 00163 FILE *jfp; 00164 UINT jpeg_input(JDEC *jd, BYTE *buff, UINT ndata) 00165 { 00166 if (buff) { 00167 int n = fread(buff, 1, ndata, jfp); 00168 return(n == -1 ? 0 : n); 00169 } 00170 return(fseek(jfp, ndata, SEEK_CUR) == -1 ? 0 : ndata); 00171 } 00172 00173 int16_t Cover_tlx, Cover_tly; 00174 00175 UINT jpeg_output(JDEC *jd, void *bitmap, JRECT *rect) 00176 { 00177 WORD *src = (WORD *)bitmap; 00178 00179 int x0 = rect->left; 00180 int x1 = rect->right; 00181 int y0 = rect->top; 00182 int y1 = rect->bottom; 00183 int w = x1 - x0 + 1; 00184 00185 if (x0 >= TFT_MAX_X || y0 >= TFT_MAX_Y) return 1; 00186 if (x1 >= TFT_MAX_X) x1 = TFT_MAX_X - 1; 00187 if (y1 >= TFT_MAX_Y) y1 = TFT_MAX_Y - 1; 00188 00189 for (int y = y0; y <= y1; y++) { 00190 TFT_setXY(Cover_tlx + x0, Cover_tly + y); 00191 WORD *p = src + w * (y - y0); 00192 for (int x = x0; x <= x1; x++) 00193 TFT_wr_data(*p++); 00194 } 00195 return 1; 00196 } 00197 00198 00199 #define MM_TLX 0 00200 #define MM_TLY (TFT_MAX_Y - bmpYsize) 00201 #define MM_YH bmpYsize 00202 00203 #define MM_FR 80 00204 #define MM_PLAY (MM_FR + 50) 00205 #define MM_FF (MM_PLAY + 54) 00206 #define MM_FFE (MM_FF + 50) 00207 #define MM_VUPD (TFT_MAX_X - 58) 00208 00209 #define MM_VUP (TFT_MAX_Y - bmpYsize) 00210 #define MM_VDWN (TFT_MAX_Y - (bmpYsize / 2)) 00211 00212 uint16_t tp_menu() 00213 { 00214 int16_t wposX, wposY; 00215 00216 if (TPC_getXY(&wposX, &wposY) == 2) { 00217 if (wposY < MM_TLY) return(PS_SEEK); 00218 if (wposX < MM_FR ) return(0); 00219 if (wposX < MM_PLAY) return(PS_FFR); 00220 else if (wposX < MM_FF ) return(PS_PAUSE); 00221 else if (wposX < MM_FFE ) return(PS_FFF); 00222 else if (wposY < MM_VDWN) return(PS_VUP); 00223 else if (wposY > MM_VDWN) return(PS_VDOWN); 00224 } 00225 return(0); 00226 } 00227 00228 //#define SEEK_Dump() 00229 #define SEEK_Dump() pc.printf("%d - (%8d - %d = %8d) = %8d(%8d)\n", Wave_Size,Wave_FPos,Wave_Play,Wave_FPos-Wave_Play,Wave_Rlen,Wave_Rlen-(Wave_Size-(Wave_FPos-Wave_Play))) 00230 00231 uint16_t event_chk() 00232 { 00233 static uint16_t stepS = 0, timep, barp, bcp; 00234 static int16_t tp_cnt = 0; 00235 00236 int16_t px, py; 00237 uint16_t statN = 0, tw, barl, bc; 00238 char times[8]; 00239 00240 while (1) { 00241 switch (stepS) { 00242 case 0: 00243 case 50: 00244 tw = (Wave_FPos - Wave_Play) / (Wave_BPS * 4); // (Wave_FPos * 8) / (Wave_BPS * 16 * 4) 00245 if (tw != timep) { 00246 timep = tw; 00247 sprintf(times, "%02d:%02d", (timep / 60), (timep % 60)); 00248 TFT_drawText( 28, (TFT_MAX_Y - 1) - 6 - (bmpYsize / 2), (uint8_t*)times, WHITE, BLACK); 00249 barp = 0; 00250 } 00251 stepS += 10; 00252 break; 00253 00254 case 10: 00255 case 60: 00256 barl = (((Wave_FPos - Wave_Play) / 1000) * TFT_MAX_X) / (Wave_Size / 1000); 00257 bc = (ps_stat & PS_PAUSE) ? YELLOW : BLUE; 00258 if ((stepS >= 50) || (barp != barl) || (bcp != bc)) { 00259 TFT_fillRectangle( 0, (TFT_MAX_Y - 1) - bmpYsize - 2, barl, (TFT_MAX_Y - 1) - bmpYsize, bc, bc); 00260 if (barl < (TFT_MAX_X - 1)) 00261 TFT_fillRectangle(barl, (TFT_MAX_Y - 1) - bmpYsize - 2, (TFT_MAX_X - 1), (TFT_MAX_Y - 1) - bmpYsize, BLACK, BLACK); 00262 barp = barl; 00263 bcp = bc; 00264 } 00265 if (stepS > 50) stepS += 10; 00266 else stepS = 20; 00267 break; 00268 00269 case 70: 00270 if (TPC_getXY(&px, &py) == 2) { 00271 if (px < ((320 * 1) / 10)) px = ((320 * 1) / 10); 00272 if (px > ((320 * 9) / 10)) px = ((320 * 9) / 10); 00273 if (px < ((320 * 1) / 7)) { 00274 if (Wave_FPos < (Wave_BPS * 2 * 2 * 2)) { 00275 SEEK_Dump(); 00276 statN = PS_FFR; 00277 tp_cnt = 0; 00278 stepS = 0; 00279 break; 00280 } 00281 Wave_FPos = Wave_Play; 00282 Wave_Rlen = Wave_Size; 00283 } else if (px >= ((320 * 9) / 10)) { 00284 Wave_FPos = Wave_Play + Wave_Size; 00285 Wave_Rlen = 0; 00286 } else { 00287 uint64_t pr = (px - ((320 * 1) / 10)) * 1000 / (((320 * 8) / 10)); 00288 Wave_FPos = ((Wave_Size * pr) / 1000); 00289 if (Wave_FPos > (Wave_Play + Wave_Size)) Wave_FPos = Wave_Size + Wave_Play; 00290 if (Wave_FPos < Wave_Play) Wave_FPos = Wave_Play; 00291 Wave_Rlen = Wave_Size - (Wave_FPos - Wave_Play); 00292 } 00293 } else { 00294 tp_cnt++; 00295 if (tp_cnt > 100) { 00296 if (Wave_FPos < Wave_Size + Wave_Play) { 00297 Wave_FPos &= (uint64_t)-BUFF_SIZE; 00298 if (Wave_FPos < Wave_Play) Wave_FPos = Wave_Play; 00299 Wave_Rlen = Wave_Size - (Wave_FPos - Wave_Play); 00300 } 00301 SEEK_Dump(); 00302 statN = PS_SEEK; 00303 tp_cnt = 0; 00304 stepS = 0; 00305 break; 00306 } 00307 } 00308 stepS = 50; 00309 break; 00310 00311 case 20: 00312 if (tp_stat != 0) { 00313 stepS = 22; 00314 break; 00315 } 00316 tp_stat = tp_menu(); 00317 tp_cnt = 0; 00318 if (tp_stat & PS_SEEK) { 00319 ps_stat |= PS_PAUSE; 00320 stepS = 50; 00321 SEEK_Dump(); 00322 break; 00323 } 00324 if (tp_stat == 0) stepS = 0; 00325 else stepS = 22; 00326 break; 00327 00328 case 22: 00329 tp_statN = tp_menu(); 00330 if (tp_statN == 0) { 00331 tp_cnt = 0; 00332 tp_stat = 0; 00333 stepS = 0; 00334 break; 00335 } 00336 if (tp_stat == tp_statN) { 00337 if (tp_cnt != -1) tp_cnt++; 00338 stepS = 24; 00339 break; 00340 } 00341 tp_cnt = 0; 00342 tp_stat = tp_statN; 00343 stepS = 22; 00344 break; 00345 00346 case 24: 00347 if (tp_cnt > 1) { 00348 if (tp_stat & PS_VUP) { 00349 if (tp_cnt == 3) statN = tp_stat; 00350 if (tp_cnt >= 5) tp_cnt = 0; 00351 } else if (tp_stat & PS_VDOWN) { 00352 if (tp_cnt == 2) statN = tp_stat; 00353 if (tp_cnt >= 3) tp_cnt = 0; 00354 } else { 00355 statN = tp_stat; 00356 tp_cnt = -1; 00357 } 00358 } 00359 stepS = 0; 00360 break; 00361 00362 default: 00363 stepS = 0; 00364 break; 00365 } 00366 if (stepS < 50) break; 00367 } 00368 return(statN); 00369 } 00370 00371 00372 void poll() 00373 { 00374 uint16_t statN; 00375 char stext[8]; 00376 00377 if ((statN = event_chk()) == 0) return; 00378 if (statN & PS_PAUSE) { ps_stat ^= PS_PAUSE; return; } 00379 if (statN & (PS_FFR | PS_FFF | PS_SEEK)) { ps_stat |= statN; return; } 00380 if (statN & (PS_VUP | PS_VDOWN)) { 00381 if (statN & PS_VUP) { 00382 if (Line_Vols < 32) { Line_Vol -= (Line_Vols >= 16 ? 10 : 40); Line_Vols++; } 00383 } else { 00384 if (Line_Vols > 0) { Line_Vol += (Line_Vols > 16 ? 10 : 40); Line_Vols--; } 00385 } 00386 sprintf(stext, "%2d", Line_Vols); 00387 TFT_drawText((TFT_MAX_X - 76), (TFT_MAX_Y - 1) - 6 - (bmpYsize / 2), (uint8_t*)stext, WHITE, BLACK); 00388 Pwm_Ratio = ((65536 / PWM_CLKMHZ) / Wave_Prid) + Line_Vol; 00389 } 00390 return; 00391 } 00392 00393 00394 DIR *dp; 00395 FILE *fp; 00396 struct dirent *p; 00397 00398 int Open_Wave(char *path) 00399 { 00400 fp = fopen(path, "rb"); 00401 if (fp == NULL) return (Last_Err = -3); // can't open 00402 00403 buffLN[0] = fread(Wave_buff[0], 1, BUFF_SIZE, fp); 00404 if (buffLN[0] < 46) return (Last_Err = -4); // invalid file 00405 00406 // "RIFF", (long)File size, "WAVE" 00407 if ((_WU32(0, 0) != 0x46464952) || 00408 (_WU32(0, 8) != 0x45564157)) 00409 return (Last_Err = -5); // invalid file 00410 00411 buffGP = 12; 00412 while (buffGP < BUFF_SIZE) { 00413 unsigned long tagn = _WU32(0, buffGP); 00414 unsigned long tagl = _WU32(0, buffGP + 4); 00415 buffGP += 8; 00416 00417 if (tagn == 0x20746D66) { // "fmt " 00418 Wave_CHs = _WU16(0, buffGP + 2); 00419 Wave_BPS = _WU32(0, buffGP + 4); 00420 Wave_Bits = _WU32(0, buffGP +14); 00421 Wave_Prid = 2000000 / Wave_BPS; 00422 if (Wave_Prid & 1) Wave_Prid++; 00423 Wave_Prid >>= 1; 00424 } 00425 00426 // "fact" 0x74636166) 00427 // "LIST" 0x74636166) 00428 if (tagn != 0x61746164) { // !"data" 00429 buffGP += tagl; 00430 continue; 00431 } 00432 00433 if ((Wave_BPS == 24000) || 00434 (Wave_BPS == 32000) || 00435 (Wave_BPS == 44100) || 00436 (Wave_BPS == 48000)) { 00437 Wave_Size = tagl; 00438 return 0; 00439 } 00440 break; 00441 } 00442 return (Last_Err = -6); // invalid file 00443 } 00444 00445 00446 int music_nw, music_nx; 00447 00448 int Play_Wave() 00449 { 00450 int32_t getln; 00451 00452 if (((buffNX != -1) && (buffLN[buffNX] == 0)) ||(ps_stat & (PS_SEEK | PS_FFR))) { 00453 statLED1 = LHigh; 00454 if (ps_stat & (PS_SEEK | PS_FFR)) { 00455 if (fseek(fp, Wave_FPos, SEEK_SET) == -1) { 00456 ps_stat |= PS_EOF; 00457 buffNX = -1; 00458 return (Last_Err = -7); // read error 00459 } 00460 Wave_Rlen = Wave_Size - (Wave_FPos - Wave_Play); 00461 ps_stat &= ~PS_FFR; 00462 } 00463 00464 if (Wave_FPos <= Wave_Play) 00465 getln = ((BUFF_SIZE - Wave_Play) > Wave_Rlen) ? Wave_Rlen : (BUFF_SIZE - Wave_Play); 00466 else 00467 getln = (Wave_Rlen > BUFF_SIZE) ? BUFF_SIZE : Wave_Rlen; 00468 if (getln && (buffNX != -1)) { 00469 if (fread(Wave_buff[buffNX], 1, getln, fp) != getln) { 00470 ps_stat |= PS_EOF; 00471 buffNX = -1; 00472 return (Last_Err = -7); // read error 00473 } 00474 buffLN[buffNX] = getln & -4; 00475 Wave_FPos += getln; 00476 if (Wave_Rlen > getln) Wave_Rlen -= getln; else Wave_Rlen = 0; 00477 00478 if (ps_stat & PS_SEEK) { 00479 buffLN[buffNW] = buffLN[buffNX]; 00480 SWBuff(); 00481 ps_stat &= ~(PS_SEEK | PS_PAUSE); 00482 } 00483 } 00484 statLED1 = LLow; 00485 00486 if (Wave_Rlen == 0) { 00487 buffNX = -1; 00488 ps_stat |= PS_EOF; 00489 wait_ms(50); 00490 return(0); 00491 } 00492 return getln; 00493 } 00494 00495 if (ps_stat & PS_PAUSE) return(1); 00496 return 0; 00497 } 00498 00499 00500 #if defined(Test) 00501 int main() 00502 { 00503 if (Open_Wave("/" FILESYS "/music/01.wav")) error("open error\n"); 00504 00505 Pwm_Ratio = ((65535 / PWM_CLKMHZ) / Wave_Prid) + Line_Vol; 00506 buffNW = 0, buffNX = 1; 00507 buffLN[buffNX] = 0; 00508 00509 Line_R.period_us(Wave_Prid); 00510 Line_L.period_us(Wave_Prid); 00511 Tick_Timer.attach_us(&ISR_Tick, Wave_Prid); 00512 00513 pc.printf("start\n"); 00514 while (1) { 00515 if (buffLN[buffNX] == 0) { 00516 if (fread(Wave_buff[buffNX], 1, BUFF_SIZE, fp) != BUFF_SIZE) break; 00517 if (Wave_Size >= BUFF_SIZE) Wave_Size -= BUFF_SIZE; else break; 00518 buffLN[buffNX] = BUFF_SIZE; 00519 } 00520 } 00521 Tick_Timer.detach(); 00522 fclose(fp); 00523 pc.printf("stop\n"); 00524 } 00525 00526 #else 00527 00528 int main() 00529 { 00530 char path[256], msc_file[256], stext[20]; 00531 00532 pc.baud(115200); 00533 TFT_init(); 00534 TPC_Init(); 00535 TFT_clearScreen(GRAY); 00536 00537 while (1) { 00538 00539 // Open Music Directory 00540 // --------------------- 00541 if (sd.disk_initialize()) return -1; 00542 00543 BMP24Bits(0, (TFT_MAX_Y - 1), "/" FILESYS "/images/Play.bmp"); 00544 dp = 0, music_nw = 1, music_nx = 1; 00545 00546 while (1) { 00547 00548 // Get Music file(.wav) 00549 // --------------------- 00550 { 00551 int i; 00552 00553 if (music_nw >= music_nx) { 00554 if (dp) closedir(dp); 00555 dp = opendir("/" FILESYS "/music"); 00556 if (dp == NULL) { 00557 pc.printf("\n" "/" FILESYS "/music/ open error.\n"); 00558 return 0; 00559 } 00560 music_nw = 0; 00561 } 00562 00563 if ((p = readdir(dp)) == NULL) break; 00564 for (i = 0; p->d_name[i]; i++) 00565 msc_file[i] = p->d_name[i]; 00566 msc_file[i] = '\0'; 00567 00568 if (msc_file[i - 4] == '.') msc_file[i - 4] = '\0'; 00569 if (strcmp(p->d_name + (i - 3), "wav") != 0) { 00570 pc.printf("Skip - music/%s\n", p->d_name); 00571 continue; 00572 } 00573 00574 if (++music_nw < music_nx) continue; 00575 music_nx++; 00576 } 00577 00578 // View Navigate(Play time, Sound volume) 00579 // --------------------------------------- 00580 { 00581 snprintf(path, sizeof path, "/" FILESYS "/music/%s", msc_file); 00582 pc.printf("Play - %s\n", path); 00583 00584 TFT_fillRectangle( 0, 0, 319, 239 - bmpYsize, GRAY, GRAY); 00585 TFT_drawText( 28, 239 - 6 - (bmpYsize / 2), (uint8_t*)"00:00", WHITE, BLACK); 00586 sprintf(stext, "%2d", Line_Vols); 00587 TFT_drawText(244, 239 - 6 - (bmpYsize / 2), (uint8_t*)stext, WHITE, BLACK); 00588 TFT_fillRectangle( 0, 239 - bmpYsize - 2, 319, 239 - bmpYsize, BLACK, BLACK); 00589 } 00590 00591 // View Image 00592 // ----------- 00593 { 00594 JDEC jdec; 00595 WORD work[4000/sizeof(WORD)]; 00596 00597 snprintf(path, sizeof path, "/" FILESYS "/music/%s" ".jpg", msc_file); 00598 pc.printf("jpg - %s\n", path); 00599 jfp = fopen(path, "rb"); 00600 if (!jfp) jfp = fopen("/" FILESYS "/images/NoImage.jpg", "rb"); 00601 if (jfp) { 00602 JRESULT r = jd_prepare(&jdec, jpeg_input, work, sizeof(work), jfp); 00603 if (r == JDR_OK) { 00604 uint16_t ww = jdec.width & 0x3FF; // struct jdec ??? 00605 uint16_t wh = jdec.width >> 16; // .. 00606 Cover_tlx = (ww < 170) ? ((176 - ww) / 2) : 4; 00607 Cover_tly = (wh < 180) ? ((188 - wh) / 2) : 4; 00608 r = jd_decomp(&jdec, jpeg_output, 0); 00609 #if (0) 00610 TFT_drawLine(Cover_tlx + 1, Cover_tly + wh, Cover_tlx + ww, Cover_tly + wh, WHITE); 00611 TFT_drawLine(Cover_tlx + ww, Cover_tly + 1, Cover_tlx + ww, Cover_tly + wh, WHITE); 00612 #endif 00613 } 00614 fclose(jfp); 00615 } 00616 } 00617 00618 // View Song title 00619 // ---------------- 00620 { 00621 int l = 0; 00622 char msc_Text[256]; 00623 00624 snprintf(path, sizeof path, "/" FILESYS "/music/%s" ".txt", msc_file); 00625 pc.printf("txt - %s\n", path); 00626 00627 fp = fopen(path, "r"); 00628 if (fp) { 00629 l = fread(msc_Text, 1, 256, fp); 00630 fclose(fp); 00631 } 00632 00633 if (l > 4) 00634 msc_Text[l] = '\0'; 00635 else snprintf(msc_Text, sizeof(msc_Text), "||%s||", msc_file); 00636 pc.printf("%02d - %s\n\n", music_nw, msc_Text); 00637 00638 int ps, pl = 0; 00639 int px = 176, py = Cover_tly + 2; 00640 uint8_t ws[2]; 00641 ws[1] = '\0'; 00642 00643 for (ps = 0; ps < 256; ps++) { 00644 if (msc_Text[ps] == '|') { 00645 if (++pl > 2) break; 00646 py += 20; 00647 px = 176; 00648 continue; 00649 } 00650 if (msc_Text[ps] & 0x80) { // KANJI ? 00651 font.read((msc_Text[ps] << 8)| msc_Text[ps + 1]); 00652 draw_kanji(px, py, ((pl == 2) ? WHITE : DWHITE), GRAY); 00653 px += 16; 00654 ps++; 00655 } else { 00656 ws[0] = msc_Text[ps]; 00657 TFT_drawText(px, py + 2, ws, ((pl == 2) ? WHITE : DWHITE), GRAY); 00658 px += 8; 00659 } 00660 } 00661 } 00662 00663 // Play Music 00664 // ----------- 00665 { 00666 snprintf(path, sizeof path, "/" FILESYS "/music/%s" ".wav", msc_file); 00667 int rc = Open_Wave(path); 00668 if (rc) { 00669 if (fp != NULL) fclose(fp); 00670 pc.printf(" rc=%d, Last_Err=%d\n", rc, Last_Err); 00671 Last_Err = 0; 00672 continue; 00673 } 00674 00675 uint16_t tw = Wave_Size / (Wave_BPS * 4); 00676 sprintf(stext, "%02d %2dks %02d:%02d", music_nw, (Wave_BPS / 1000), (tw / 60), (tw % 60)); 00677 TFT_drawText(214, (222 - bmpYsize), (uint8_t*)stext, BLACK, GRAY); 00678 00679 Wave_Play = buffGP; 00680 Wave_FPos = BUFF_SIZE; 00681 Wave_Rlen = Wave_Size - (Wave_FPos - Wave_Play); 00682 buffNW = 0, buffNX = 1; 00683 buffLN[buffNX] = 0; 00684 00685 Last_Err = 0; 00686 ps_stat = PS_PLAY; 00687 00688 Pwm_Ratio = ((65535 / PWM_CLKMHZ) / Wave_Prid) + Line_Vol; 00689 Line_R.period_us(Wave_Prid); 00690 Line_L.period_us(Wave_Prid); 00691 Tick_Timer.attach_us(&ISR_Tick, Wave_Prid); // Play! 00692 00693 while (!(ps_stat & PS_EOF) && (ps_stat & PS_PLAY) && (Last_Err == 0)) { 00694 00695 #if defined(Level_Indicator) 00696 uint16_t yl0 = 0, yr0 = 0, yl, yr; 00697 if (Pwm_cnt > Level_Indicator) { 00698 yl = 238 - (((Pwm_aveL - 64) * (bmpYsize - 2)) / 200); 00699 yr = 238 - (((Pwm_aveR - 64) * (bmpYsize - 2)) / 200); 00700 Pwm_cnt = 0; 00701 if (yl > 237) yl = 238; 00702 if (yr > 237) yr = 238; 00703 yl0 = (yl > yl0) ? yl : ((yl0 + yl) / 2); 00704 yr0 = (yr > yr0) ? yr : ((yr0 + yl) / 2); 00705 TFT_fillRectangle(MM_VUPD + 5, MM_VUP + 1, MM_VUPD + 7, yl0, BLACK, BLACK); 00706 TFT_fillRectangle(MM_VUPD + 9, MM_VUP + 1, MM_VUPD + 11, yr0, BLACK, BLACK); 00707 if (yl0 < 238) TFT_fillRectangle(MM_VUPD + 5, yl0, MM_VUPD + 7, 238, YELLOW, YELLOW); 00708 if (yr0 < 238) TFT_fillRectangle(MM_VUPD + 9, yr0, MM_VUPD + 11, 238, YELLOW, YELLOW); 00709 } 00710 #endif 00711 00712 if (Play_Wave()) { 00713 00714 statLED4 = LHigh; 00715 if (ps_stat & PS_PAUSE) wait_ms(5); 00716 poll(); 00717 statLED4 = LLow; 00718 00719 if (ps_stat & PS_FFF) { 00720 buffNX = -1; 00721 break; 00722 } 00723 00724 if (ps_stat & PS_FFR) { 00725 if (Wave_FPos < (Wave_BPS * 2 * 2 * 2)) { 00726 buffNX = -1; 00727 if (music_nx > music_nw) 00728 music_nx = (music_nw > 1) ? music_nw - 1 : 1; 00729 break; 00730 } else 00731 Wave_FPos = Wave_Play; 00732 } 00733 } 00734 } 00735 00736 Tick_Timer.detach(); 00737 fclose(fp); 00738 pc.printf("Close stat=%04X, %d - %d\n", ps_stat, Wave_Rlen, Last_Err); 00739 ps_stat = 0; 00740 Last_Err = 0; 00741 } 00742 } 00743 closedir(dp); 00744 } 00745 } 00746 #endif
Generated on Tue Jul 19 2022 23:14:24 by 1.7.2