void SongListFile(const wchar_t* filename) { PLAYERINFO* playerinfo = new PLAYERINFO(); ZeroMemory(playerinfo, sizeof(PLAYERINFO)); playerinfo->cd = FALSE; playerinfo->filename = WideCharToChar(filename, wcslen(filename)); InitializeCriticalSection(&playerinfo->lock_lyric); InitializeCriticalSection(&playerinfo->lock_lyricinfo); if (DecodeInit(playerinfo->filename, &playerinfo->decode)) { PWAVEFORMATEXTENSIBLE waveformatEx = &playerinfo->dx.waveformatEx; PLAYERDECODE* decode = &playerinfo->decode; WaveFormatInit(waveformatEx, decode); DecodeTag(playerinfo); PlayInfoRelease(playerinfo, FALSE); } else { PlayInfoRelease(playerinfo, TRUE); return; } if (first == NULL) { playerinfo->n = 0; first = playerinfo; last = playerinfo; } else { playerinfo->n = last->n + 1; last->next = playerinfo; last = playerinfo; } PLAYERTAG* tag = &playerinfo->tag; LVITEM lv = {0}; lv.mask = LVIF_TEXT | LVIF_COLUMNS; lv.pszText = L""; lv.iItem = ListView_GetItemCount(songlist.hWnd); int p = ListView_InsertItem(songlist.hWnd, &lv); if (tag->title != NULL) { ListView_SetItemText(songlist.hWnd, p, 1, tag->title); } else { ListView_SetItemText(songlist.hWnd, p, 1, L""); } if (tag->artist != NULL) { ListView_SetItemText(songlist.hWnd, p, 2, tag->artist); } else { ListView_SetItemText(songlist.hWnd, p, 2, L""); } ListView_SetItemText(songlist.hWnd, p, 3, tag->timer); }
/* Actual MDI protocol implementation *****************************************/ void CMDI::DecAFPacket(CVector<_BINARY>& vecbiAFPkt) { int i; /* CRC check ------------------------------------------------------------ */ CCRC CRCObject; // FIXME: is this length always the correct length? In the actual packet // there is also a value for the length included!!!???!??? const int iLenAFPkt = vecbiAFPkt.Size(); /* We do the CRC check at the beginning no matter if it is used or not since we have to reset bit access for that */ /* Reset bit extraction access */ vecbiAFPkt.ResetBitAccess(); /* Check the CRC of this packet */ CRCObject.Reset(16); /* "- 2": 16 bits for CRC at the end */ for (i = 0; i < iLenAFPkt / SIZEOF__BYTE - 2; i++) CRCObject.AddByte((_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE)); const _BOOLEAN bCRCOk = CRCObject.CheckCRC(vecbiAFPkt.Separate(16)); /* Actual packet decoding ----------------------------------------------- */ vecbiAFPkt.ResetBitAccess(); /* SYNC: two-byte ASCII representation of "AF" (2 bytes) */ string strSyncASCII = ""; for (i = 0; i < 2; i++) strSyncASCII += (_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE); /* Check if string is correct */ if (strSyncASCII.compare("AF") != 0) return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! /* LEN: length of the payload, in bytes (4 bytes long -> 32 bits) */ const int iPayLLen = (int) vecbiAFPkt.Separate(32); /* SEQ: sequence number. Each AF Packet shall increment the sequence number by one for each packet sent, regardless of content. There shall be no requirement that the first packet received shall have a specific value. The counter shall wrap from FFFF_[16] to 0000_[16], thus the value shall count, FFFE_[16], FFFF_[16], 0000_[16], 0001_[16], etc. (2 bytes long -> 16 bits) */ // TODO: use sequence number somehow!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! const int iCurSeqNum = (int) vecbiAFPkt.Separate(16); /* iSeqNumber++; if (iSeqNumber > 0xFFFF) iSeqNumber = 0; */ /* AR: AF protocol Revision - a field combining the CF, MAJ and MIN fields */ /* CF: CRC Flag, 0 if the CRC field is not used (CRC value shall be 0000_[16]) or 1 if the CRC field contains a valid CRC (1 bit long) */ if ((_BOOLEAN) vecbiAFPkt.Separate(1)) { /* Use CRC check which was already done */ if (!bCRCOk) return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! } /* MAJ: major revision of the AF protocol in use (3 bits long) */ const int iMajRevAFProt = (int) vecbiAFPkt.Separate(3); /* MIN: minor revision of the AF protocol in use (4 bits long) */ const int iMinRevAFProt = (int) vecbiAFPkt.Separate(4); // TODO: check if protocol versions match our version!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /* Protocol Type (PT): single byte encoding the protocol of the data carried in the payload. For TAG Packets, the value shall be the ASCII representation of "T" */ if ((_BYTE) vecbiAFPkt.Separate(SIZEOF__BYTE) != 'T') return; // TODO: error handling!!!!!!!!!!!!!!!!!!!!!! /* Payload -------------------------------------------------------------- */ CMDIInPkt MIDInPkt; /* Decode all tags */ int iCurConsBytes = 0; /* Each tag must have at least a header with 8 bytes -> "- 8" */ while (iCurConsBytes < iPayLLen - 8) iCurConsBytes += DecodeTag(MIDInPkt, vecbiAFPkt); /* Add new MDI data to buffer */ MDIInBuffer.Put(MIDInPkt); }
DWORD WINAPI MainThread(LPVOID param) { while (TRUE) { DWORD ret = WaitForSingleObject(main_wnd.handle, INFINITE); if (ret == WAIT_OBJECT_0) { if (playerstatus == ID_STATUS_STOP) { ResetEvent(main_wnd.handle); continue; } if (playerstatus == ID_STATUS_START) { ResetEvent(main_wnd.handle); PLAYERINFO* playerinfo = player.current; BOOL success = FALSE; if (playerinfo->cd) success = DecodeCDInit(playerinfo); else success = DecodeInit(playerinfo->filename, &playerinfo->decode); if (success) { PWAVEFORMATEXTENSIBLE waveformatEx = &playerinfo->dx.waveformatEx; PLAYERDECODE* decode = &playerinfo->decode; WaveFormatInit(waveformatEx, decode); if (playerinfo->cd) DecodeCDTag(playerinfo); else DecodeTag(playerinfo); PWAVEFORMATEX waveformat = &waveformatEx->Format; DspSet(waveformat->nSamplesPerSec, waveformat->nChannels, waveformat->nBlockAlign); if (DxBufferInit(playerinfo)) { SetWindowText(playerinfo); if (!playerinfo->cd) { LyricStart(); LyricSearchArtistTile(playerinfo); } TrackEnable(TRUE); DxPlay(playerinfo, &playerstatus); } } if (playerstatus == ID_STATUS_START || playerstatus == ID_STATUS_PAUSE) playerstatus = ID_STATUS_STOP; TrackEnable(FALSE); LyricStop(); LyricSearchClear(); SpectrumStop(); ClockInfoStop(); playerinfo->playing = FALSE; playerinfo->pause = FALSE; SetWindowText(playerinfo); RefreshItem(playerinfo->n); PLAYERINFO* next = playerinfo->next; if (player.stop) player.current = NULL; else { if (player.entry) { playerstatus = ID_STATUS_START; player.current = player.next; player.next = NULL; player.entry = FALSE; if (player.current->n == -1 && playerinfo->n != -1) player.current->next = playerinfo; SetEvent(main_wnd.handle); } else { if (next != NULL) { playerstatus = ID_STATUS_START; player.current = next; player.next = NULL; player.entry = FALSE; SetEvent(main_wnd.handle); } else player.current = NULL; } } PlayInfoRelease(playerinfo, FALSE); } if (playerstatus == ID_STATUS_EXIT) { if (player.next != NULL) PlayInfoRelease(player.next, FALSE); CDROMRelease(); break; } } } SpectrumExit(); ClockInfoExit(); SongListExit(); LyricSearchExit(); LyricExit(); Gdiplus::GdiplusShutdown(main_wnd.gdiToken); PostMessage(main_wnd.hWnd, WM_QUIT, 0, 0); return 1; }