VLSI Solution Oy VLSI Solution Oy Evaluation MP3 Player Source Code Documentation

Main Page | Class List | File List | Class Members | File Members | Related Pages

player.c

Go to the documentation of this file.
00001 00191 #include "board.h" 00192 #include "lcd.h" 00193 #include "filesys.h" 00194 #include "vs10xx.h" 00195 #include "storage.h" 00196 #include "display.h" 00197 #include "string.h" 00198 #include "ui.h" 00199 #include "mmc.h" 00200 #include "record.h" 00201 00202 00204 #define u_int8 code unsigned char 00205 00206 #define u_int16 code unsigned int 00207 00208 //include a patch code module 00209 #ifdef VS1003 00210 #include "spec_rew.c" 00211 #else 00212 #include "loud_sa.c" 00213 #endif 00214 00215 00216 00218 #define UI_RETURN_DELAY 150 00219 00221 xdata playingstatetype playingState = PS_NORMAL; 00222 00224 unsigned char intlevel = 0; 00225 00228 xdata unsigned char userInterfaceDelayElapsed = 0; 00229 00231 xdata uimodetype uiMode = UI_SPEC; 00232 00233 xdata unsigned char SPMax=0; 00234 00235 00236 00241 void timer0_interrupt(void) interrupt 1{ 00242 static char displayDelay; 00243 userInterfaceDelayElapsed = 1; 00244 if (++displayDelay==12){ 00245 displayDelay = 0; 00246 displayPosition++; 00247 if (displayPosition>displayLength+7){ 00248 displayPosition = -7; 00249 } 00250 } 00251 if (SP>SPMax) SPMax = SP; 00252 00253 00254 } 00255 00256 00257 00258 00260 void LoadPatch(){ 00261 ConsoleWrite ("Loading patch.\r"); 00262 for (temp.i=0; temp.i < CODELEN; temp.i++) { 00263 Mp3WriteRegister(atab[temp.i], dtab[temp.i]>>8, dtab[temp.i]&0xff); 00264 } 00265 Delay(10); 00266 } 00267 00269 void StartPatch() 00270 { 00271 00272 #ifdef VS1003 00273 // Mp3WriteRegister(SPI_AIADDR, 0x00, 0x50); 00274 #else 00275 //Mp3WriteRegister(SPI_AIADDR, 0x02, 0x00); 00276 //Mp3WriteRegister(SPI_AICTRL0, 0x00, 0x00); 00277 //Mp3WriteRegister(SPI_AICTRL0, 0x00, 0x01); 00278 #endif 00279 } 00280 00281 00282 00283 00285 void ScreenSetPlayTime(){ 00286 unsigned int playTime; 00287 unsigned char minutes, seconds; 00288 00289 playTime = Mp3ReadRegister(SPI_DECODE_TIME); 00290 minutes = playTime/60; 00291 seconds = playTime%60; 00292 displayTitle[0]=('0'+minutes/10); 00293 displayTitle[1]=('0'+minutes%10); 00294 displayTitle[2]=(':'); 00295 displayTitle[3]=('0'+seconds/10); 00296 displayTitle[4]=('0'+seconds%10); 00297 displayTitle[5]=(' '); 00298 displayTitle[6]=(' '); 00299 displayTitle[7]=(' '); 00300 00301 if (seconds&1){ 00302 if (playingState == PS_RECORDING){ 00303 displayTitle[6]='o'; 00304 }else{ 00305 displayTitle[6]='\x7e'; 00306 } 00307 00308 } 00309 00310 if ((playingState != PS_NORMAL)&&(playingState != PS_RECORDING)){ 00311 displayTitle[6]='\xdb'; 00312 } 00313 00314 00315 00316 } 00317 00318 00319 00320 00321 00322 00323 00327 void AvailableProcessorTime(){ 00328 00332 static xdata unsigned char volume = 20; 00333 00335 static xdata unsigned char bass = 0; 00336 00338 static xdata unsigned char treble = 64; //middle setting = 0 00339 00341 static xdata unsigned char reclevel = 50; 00342 00343 unsigned int i; //temp variable 00344 00345 static bit bassUpdateNeeded; 00346 00350 static unsigned char uiReturnDelay=0; 00351 00352 if (!userInterfaceDelayElapsed){ 00353 return; /* Not yet time to do user interface stuff */ 00354 } 00355 00356 userInterfaceDelayElapsed = 0; 00357 00358 00359 // User Interface Modes 00360 // Return to UI_TITLE after long period of button inactivity 00361 00362 if (uiReturnDelay == 0){ 00363 if ((uiMode != UI_SPEC)&&(uiMode != UI_CUE)) 00364 uiMode = UI_TITLE; 00365 else{ 00366 } 00367 }else{ 00368 uiReturnDelay--; 00369 } 00370 00371 #ifndef VS1003 00372 if (uiMode==UI_SPEC) //Only VS1003 has spectrum analyzer 00373 uiMode++; 00374 if (uiMode==UI_RECLEVEL) //Only record in VS1003 chips 00375 uiMode++; 00376 #endif 00377 00378 if (uiMode==UI_INFO) 00379 uiMode++; //Nothing interesting currently in screen UI_INFO. 00380 if (uiMode==UI_STOP) 00381 uiMode++; //Nothing interesting currently in screen UI_STOP. 00382 00383 /* Screen updates */ 00384 switch(uiMode){ 00385 00386 case UI_TITLE: //Playing time, song title 00387 00388 displayStyle = DS_TEXT; 00389 ScreenSetPlayTime(); 00390 00391 if (playingState==PS_RECORDING){ 00392 displayStyle = DS_PERCENTAGE; 00393 } 00394 00395 break; 00396 00397 case UI_STOP: //Ask if the user wants to stop 00398 displayStyle = DS_NO_YES; 00399 strcpy (displayTitle, "Stop? "); 00400 break; 00401 00402 case UI_CUE: //Ask if the user wants to fast forward or rewind 00403 displayStyle = DS_RAWTEXT; 00404 strcpy (displayTitle, "REW/CUE <- ->"); 00405 00406 //i = Mp3ReadRegister(SPI_HDAT1); 00407 //displayTitle[5] = lcd_hexchars[i>>12]; 00408 //displayTitle[6] = lcd_hexchars[(i>>8)&0x0f]; 00409 //displayTitle[7] = lcd_hexchars[(i>>4)&0x0f]; 00410 //displayTitle[8] = lcd_hexchars[i&0x0f]; 00411 00412 break; 00413 00414 case UI_VOLUME: //Show volume bar 00415 LcdSelectFont(lcdFont_barchars); 00416 displayStyle = DS_PERCENTAGE; 00417 strcpy(displayTitle,"Volume: "); 00418 displayValue = (100-(volume>>1)); 00419 if (displayValue<0) displayValue = 0; 00420 break; 00421 00422 case UI_BASS: //Show bass bar 00423 LcdSelectFont(lcdFont_barchars); 00424 displayStyle = DS_PERCENTAGE; 00425 strcpy(displayTitle,"Bass: "); 00426 displayValue = (bass/5)*4; 00427 if (displayValue<1) displayValue = 1; 00428 break; 00429 00430 case UI_TREBLE: //Show treble bar 00431 LcdSelectFont(lcdFont_barchars); 00432 displayStyle = DS_PERCENTAGE; 00433 strcpy(displayTitle,"Treble: "); 00434 displayValue = (treble/5)*4; 00435 if (displayValue<1) displayValue = 1; 00436 break; 00437 00438 case UI_RECLEVEL: //Show recording level 00439 00440 if (playingState==PS_RECORDING){ 00441 LcdSelectFont(lcdFont_barchars); 00442 displayStyle = DS_PERCENTAGE; 00443 strcpy(displayTitle,"RecLevel"); 00444 displayValue = (reclevel); 00445 if (reclevel==0){ 00446 strcpy(displayTitle,"RecLevel <Auto> "); 00447 displayStyle = DS_RAWTEXT; //Reveal the "auto" text 00448 } 00449 }else{ 00450 //Not in recording 00451 displayStyle = DS_NO_YES; 00452 strcpy (displayTitle, "Record? "); 00453 } 00454 break; 00455 00456 00457 case UI_SPEC: // Spectrum analyzer 00458 00459 if (playingState == PS_RECORDING){ 00460 uiMode++; //Don't show specana when recording 00461 } 00462 00463 LcdSelectFont(lcdFont_vertical_barchars); 00464 displayStyle = DS_RAWTEXT; 00465 ScreenSetPlayTime(); 00466 00467 // Request to read Spectrum Analyzer register 00468 Mp3WriteRegister(7, 0x18, 0x04); 00469 00470 // Read Spectrum Analyzer registers 00471 { 00472 for (i=0;i<8;i++) { //for each band i in [0..7] 00473 signed char thisband = Mp3ReadRegister(6); 00474 00475 /* thisband now has spectrum value 0..63. We adjust it a little 00476 for best image on the evakit LCD. You also get peak values 00477 etc from the chip but we don't use them in the evakit screen. 00478 we use 8 bands, but up to 23 are obtainable from the chip. */ 00479 00480 thisband &= 63; /* mask all but level info */ 00481 thisband >>= 1; /* LCD resolution is not high */ 00482 thisband -= 3; /* base offset */ 00483 if (i==0) thisband -= 2; /* decrease bass bar level */ 00484 if (i==6) thisband += 1; /* increase treble bar level */ 00485 if (i==7) thisband += 1; /* increase treble bar level */ 00486 if (thisband>7) thisband = 7; /* high limit */ 00487 if (thisband<0) thisband =' '; /* low limit */ 00488 00489 displayTitle[i+8] = thisband; //Store to display mem 00490 00491 }//for each band 00492 } 00493 break; 00494 00495 } //switch(uiMode) 00496 00497 // Buttons handler 00498 // Perform mode-dependent button handling 00499 00500 if ((KEY_BUTTON) && (uiReturnDelay < UI_RETURN_DELAY-20)){ 00501 LcdReset(); 00502 uiMode++; 00503 uiReturnDelay = UI_RETURN_DELAY; 00504 } 00505 00506 switch(uiMode){ 00507 00508 case UI_TITLE: 00509 case UI_SPEC: 00510 00511 if (KEY_FARRIGHT){ 00512 playingState = PS_NEXT_SONG; /* Request */ 00513 } 00514 if (KEY_FARLEFT){ 00515 playingState = PS_PREVIOUS_SONG; /* Request */ 00516 } 00517 break; 00518 00519 00520 case UI_VOLUME: 00521 00522 if (KEY_FARLEFT){ 00523 uiReturnDelay = UI_RETURN_DELAY; 00524 if (volume++ == 254) volume = 254; //Change + limit to 254 (minimum vol) 00525 Mp3SetVolume(volume,volume); 00526 } 00527 00528 if (KEY_FARRIGHT){ 00529 uiReturnDelay = UI_RETURN_DELAY; 00530 if (volume-- == 0) volume = 0; //Change + limit to 0 (maximum volume) 00531 Mp3SetVolume(volume,volume); 00532 } 00533 break; // UI_VOLUME 00534 00535 case UI_BASS: 00536 case UI_TREBLE: //BASS and TREBLE use the same VS10xx register 00537 bassUpdateNeeded = 0; 00538 00539 //First let's see if a key is pressed; does the user want to set level? 00540 00541 if (uiMode==UI_BASS){ //BASS screen is active 00542 00543 if (KEY_FARLEFT){ 00544 bassUpdateNeeded = 1; 00545 if (bass-- == 0) bass = 0; //Change + limit to 0 (OFF setting) 00546 } 00547 if (KEY_FARRIGHT){ 00548 bassUpdateNeeded = 1; 00549 if (bass++ == 127) bass = 127; //Change + limit to 127 (max setting) 00550 } 00551 00552 }else{ //TREBLE screen is active 00553 00554 if (KEY_FARLEFT){ 00555 bassUpdateNeeded = 1; //SCI_BASS is for both bass and treble 00556 if (treble-- == 0) treble = 0; //Change + limit to 0 (OFF setting) 00557 } 00558 if (KEY_FARRIGHT){ 00559 bassUpdateNeeded = 1; //SCI_BASS is for both bass and treble 00560 if (treble++ == 127) treble = 127; //Change + limit to 127 (max) 00561 } 00562 00563 } 00564 00565 00566 if (bassUpdateNeeded){ 00567 unsigned int newBassRegister; 00568 00569 //User has pushed button to alter bass/treble register 00570 //calculate new value 00571 00587 //Let's start from bass frequency setting. 00588 //min(0) should give 2 (20Hz), max(127) should give 15 (150Hz) 00589 newBassRegister = (bass + 23) / 10; //into bits 3..0, clear hibits 00590 00591 //Bass boost level. 00592 //min(0) should give 0, max(127) should give 15 00593 newBassRegister |= (bass>>3)<<4; //insert to bits 7..4 00594 00595 //Then the treble frequency 00596 //min(0) should give 15(15kHx), max(127) should give 2(2kHz) 00597 newBassRegister |= (((148-treble)>>3)+2)<<8; //insert into bits 11..8 00598 00599 //Finally the treble value (-8..7) 00600 //min(0) should give -8, max(127) should give 7; 00601 newBassRegister |= ((treble>>3)-8)<<12; //insert into bits 15..12 00602 00603 00604 uiReturnDelay = UI_RETURN_DELAY; 00605 00606 if (Mp3ReadRegister(SPI_BASS)!=newBassRegister){ 00607 Mp3WriteRegister(SPI_BASS,newBassRegister>>8,newBassRegister&0xff); 00608 } 00609 00610 //i = newBassRegister; 00611 //displayTitle[4] = lcd_hexchars[i>>12]; 00612 //displayTitle[5] = lcd_hexchars[(i>>8)&0x0f]; 00613 //displayTitle[6] = lcd_hexchars[(i>>4)&0x0f]; 00614 //displayTitle[7] = lcd_hexchars[i&0x0f]; 00615 00616 00617 } 00618 00619 break; // UI_BASS and UI_TREBLE 00620 00621 00622 case UI_RECLEVEL: 00623 00624 if (playingState==PS_RECORDING){ 00625 if (KEY_FARRIGHT){ 00626 uiReturnDelay = UI_RETURN_DELAY; 00627 if (reclevel++ == 100){ 00628 reclevel = 100; 00629 } 00630 Mp3WriteRegister(SPI_AICTRL1, 00631 ((int)reclevel*32)>>8,((int)reclevel*32)&0xff); 00632 SPIPutChar(0);SPIWait(); 00633 } 00634 00635 if (KEY_FARLEFT){ 00636 uiReturnDelay = UI_RETURN_DELAY; 00637 if (reclevel-- == 0){ 00638 reclevel = 0; 00639 } 00640 Mp3WriteRegister(SPI_AICTRL1, 00641 ((int)reclevel*32)>>8,((int)reclevel*32)&0xff); 00642 SPIPutChar(0);SPIWait(); 00643 } 00644 }else{ 00645 //Not in recording 00646 if (KEY_FARRIGHT){ 00647 //Enter recording mode 00648 playingState=PS_RECORDING; //request to record 00649 } 00650 } 00651 break; // UI_RECLEVEL 00652 00653 case UI_STOP: 00654 00655 if (KEY_FARRIGHT){ 00656 playingState = PS_END_OF_SONG; /* Request to abort playing */ 00657 } 00658 break; // UI_STOP 00659 00660 case UI_CUE: 00661 00662 if (playingState == PS_NORMAL){ /* Only control when PS_NORMAL */ 00663 if (KEY_FARRIGHT){ 00664 uiReturnDelay = UI_RETURN_DELAY; /* Don't go back to title just yet */ 00665 playingState = PS_CUE; /* Request */ 00666 } 00667 if (KEY_FARLEFT){ 00668 uiReturnDelay = UI_RETURN_DELAY; 00669 playingState = PS_REWIND; /* Request */ 00670 } 00671 } 00672 00673 break; // UI_SKIP 00674 00675 case UI_END_OF_MODES: 00676 uiMode = UI_TITLE; 00677 break; // UI_END_OF_MODES 00678 00679 00680 } //End Switch 00681 00682 00683 // Draw screen 00684 UpdateDisplay(); 00685 } 00686 00687 00688 00692 void PlayCurrentFile(){ 00693 xdata char c, nFragments; 00694 00695 playingState = PS_NORMAL; /* Request to play normally */ 00696 //uiMode = UI_SPEC; /* User interface: show title SPECANA FOR VS1003*/ 00697 00698 LcdLocateHome(); 00699 LcdPutConstantString("Opening "); 00700 00701 ConsoleWrite ("Building file fragment table..."); 00702 nFragments = BuildFragmentTable(); /* Too slow, rewrite! */ 00703 ConsoleWrite("\rFragments: "); 00704 ConsolePutUInt(nFragments); 00705 00706 LcdLocateHome(); 00707 LcdPutConstantString("Playing "); 00708 00709 for (c=0; c<nFragments; c++){ 00710 sectorAddress.l = fragment[c].start; 00711 ConsoleWrite ("\rPlayer: Playing from sector "); 00712 ConsolePutUInt (sectorAddress.l); 00713 if (PlayDiskSectors(fragment[c].length)!=0){ 00714 Mp3WriteRegister(SPI_MODE,0,SM_OUTOFWAV); 00715 SendZerosToVS10xx(); 00716 return; //return without touching the value of playingState 00717 } 00718 } 00719 SendZerosToVS10xx(); 00720 00721 // After finishing normally default to requesting to play next song 00722 playingState = PS_NEXT_SONG; 00723 00724 } 00725 00726 00727 00733 void main(){ 00734 00735 unsigned int currentFile; 00736 00737 InitBoard(); 00738 00739 // Start "User Interface" timer 00740 ET0 = 1; 00741 EA = 1; 00742 TR0 = 1; 00743 00744 //LcdSplashScreen(); 00745 InitDisplay (DS_STATIC," "," ",0); 00746 00747 ConsoleWrite ("\rVLSIPlayer\rStarting up.\r\r"); 00748 00749 LcdReset(); 00750 LcdPutConstantString ("Filesys "); 00751 LcdLocateLine2(); 00752 LcdPrintGenericResult (InitFileSystem()); 00753 00754 Mp3Reset(); 00755 LoadPatch(); 00756 StartPatch(); 00757 00758 // If left button is pressed during boot, enter recording. 00759 if (KEY_FARLEFT){ 00760 while(KEY_LEFT) 00761 ; 00762 Record(); 00763 } 00764 00765 00766 #ifdef VS1003 00767 uiMode = UI_SPEC; //For VS1003 default to SPECTRUM ANALYZER screen 00768 #else 00769 uiMode = UI_TITLE; //For others, default to TITLE screen 00770 #endif 00771 00772 playingState = PS_NEXT_SONG; 00773 currentFile = 1; 00774 00775 while (1){ 00776 ConsoleWrite("SPMax: ");ConsolePutHex8(SPMax); 00777 ConsoleWrite("PlayingState: ");ConsolePutHex8(playingState); 00778 00779 // has someone requested to record? 00780 if (playingState == PS_RECORDING){ 00781 uiMode = UI_TITLE; 00782 playingState = Record(); //record returns PS_NEXT_SONG or PS_RECORDING 00783 while (KEY_BUTTON) 00784 ; //Wait until button is depressed 00785 ConsoleWrite("\rFinished recording.\r"); 00786 currentFile = 1; 00787 playingState == PS_NEXT_SONG; 00788 } 00789 00790 if (OpenFile(currentFile)){ 00791 currentFile = 1; 00792 if (OpenFile(currentFile)){ 00793 LcdReset(); 00794 LcdPutConstantString("No files."); 00795 while(1); 00796 } 00797 } 00798 00799 LcdReset(); 00800 LcdPutConstantString("File "); 00801 LcdPutUInt(currentFile); 00802 LcdLocateLine2(); 00803 for (temp.c=0; temp.c<8; temp.c++){ 00804 LcdPutChar(currentFileName[temp.c]); 00805 } 00806 00807 00808 while ((KEY_BUTTON)||(KEY_FARLEFT)||(KEY_FARRIGHT)|| 00809 (KEY_LEFT)||(KEY_RIGHT)) 00810 ; /* Wait until no key is pressed */ 00811 00812 while (((!KEY_BUTTON)&&(!KEY_FARLEFT)&&(!KEY_FARRIGHT)) 00813 &&(playingState == PS_NORMAL)) 00814 ; /* Wait untis some key is pressed or playing state not normal*/ 00815 00816 00817 /* See if keystroke requests previous/next song */ 00818 if (KEY_FARLEFT) currentFile--; 00819 if (KEY_FARRIGHT) currentFile++; 00820 if (currentFile==0) currentFile = 1; 00821 00822 if (KEY_BUTTON || 00823 (playingState==PS_NEXT_SONG) || 00824 (playingState==PS_PREVIOUS_SONG)){ 00825 while (KEY_BUTTON) 00826 ; 00827 00828 PlayCurrentFile(); 00829 ConsoleWrite ("Playing state after playing is: "); 00830 ConsolePutUInt (playingState); 00831 00832 if (playingState == PS_PREVIOUS_SONG) currentFile--; 00833 if (playingState == PS_NEXT_SONG) currentFile++; 00834 if (currentFile==0) currentFile = 1; 00835 if (playingState == PS_END_OF_SONG) playingState = PS_NORMAL; 00836 00837 00838 Mp3SoftReset(); 00839 LoadPatch(); 00840 StartPatch(); 00841 00842 00843 while ((KEY_BUTTON)||(KEY_FARLEFT)||(KEY_FARRIGHT)|| 00844 (KEY_LEFT)||(KEY_RIGHT)) 00845 ; /* Wait until no key is pressed */ 00846 } 00847 00848 00849 } 00850 00851 00852 } 00853 00854

All software copyright 2000-2004 VLSI Solution OY. Redistribution of these software modules are limited to promotional use only and only with the VS1011 / VS1002 / VS1003 MP3-Evakit evaluation boards. Free or commercial use of these software modules in MP3 players is ok if the product includes MP3 decoder chip(s) from VLSI. You can request the complete (compilable) package from mp3@vlsi.fi