1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| static void CreateWaveform(IN WCHAR* audiofile) {
HSTREAM nScanChannel = BASS_StreamCreateFile(0, audiofile, 0, 0, BASS_STREAM_DECODE);
HBITMAP hDIB = 0;
static DWORD PixelArray[SCANHEIGHT][SCANWIDTH];
long nMax, nX, nY, nXpos, nLpeak, nRpeak, nL, nR;
WCHAR szFile[MAX_PATH] = { 0 };
if (nScanChannel) {
QWORD nBpp = BASS_ChannelGetLength(nScanChannel, BASS_POS_BYTE) / SCANWIDTH;
if (nBpp) {
long nHalfHeight = SCANHEIGHT / 2;
HDC hIC = zDisplayDC();
HDC hDC = CreateCompatibleDC(hIC);
hDIB = zCreateDIBSection(hDC, SCANWIDTH, SCANHEIGHT, 32);
SelectObject(hDC, hDIB);
DeleteDC(hIC);
// Must use static to avoid the default stack size limitation
ClearMemory(PixelArray, static_cast<unsigned long long>(SCANWIDTH) * SCANHEIGHT * sizeof(DWORD));
float rCoef = (float)(33 / (float)nHalfHeight);
DWORD nLevel;
nXpos = 0;
// LOOP
for (;;) {
nLevel = BASS_ChannelGetLevel(nScanChannel); // scan peaks
nLpeak = LOWORD(nLevel);
nRpeak = HIWORD(nLevel);
if (BASS_ChannelIsActive(nScanChannel) == 0) { // reached the }
break;
} else {
nX = (long)(BASS_ChannelGetPosition(nScanChannel, BASS_POS_BYTE) / nBpp);
}
if (nX > nXpos) {
if (nX >= SCANWIDTH - 1) break;
nL = (nLpeak * nHalfHeight / 32768) - 1;
nR = (nRpeak * nHalfHeight / 32768) - 1;
nMax = max(nL, nR);
for (nY = 0; nY <= nMax; nY++) {
if (nY < nL + 1) PixelArray[nHalfHeight - nY][nX] = LevelColor((long)(rCoef * nY));
// Out of bound error, because of nY + 1 below.
//if (nY < nR + 1) PixelArray[min(nHalfHeight + nY + 1, 127)][nX] = LevelColor((long)(rCoef * nY));
if (nY < nR + 1) PixelArray[nHalfHeight + nY][nX] = LevelColor((long)(rCoef * nY));
}
nXpos = nX;
}
}
ZI_SetDIBits(hDC, &PixelArray);
BASS_StreamFree(nScanChannel); // free the decoder
DeleteDC(hDC);
}
} else { // In case of music tracker
Path_Combine(szFile, EXEresource(), L"tracker.png");
hDIB = ZI_ResizeBitmapFromFile(szFile, SCANWIDTH, SCANHEIGHT);
}
RECT lpr; GetClientRect(gP.hGDImage, &lpr);
nX = (rWidth(lpr) - SCANWIDTH) / 2;
nY = (rHeight(lpr) - SCANHEIGHT) / 2;
if (hDIB) ZD_DrawBitmapToCtrl(gP.hGDImage, nX, nY, hDIB, ZD_ColorARGB(80, 0), ID_WAVEFORM, ZS_VISIBLE);
ZD_SetObjectImageLabel(ID_WAVEFORM, L"Waveform");
ZD_SetObjectZorder(ID_WAVEFORM, ZD_ORDER_BOTTOM);
ZD_SetObjectLocked(ID_WAVEFORM, TRUE);
ZD_SetObjectAnchorMode(ID_WAVEFORM, ANCHOR_CENTER);
Path_Combine(szFile, EXEresource(), L"trebuc.ttf");
if (FileExist(szFile)) {
long nID, bmW, bmH;
nID = ID_ELLAPSED_TIME;
ZD_DrawTextToCtrlEx(gP.hGDImage, L"00:00:00:00", 0, -1000, 0, 0, ZD_ARGB(192, 255,255,255), szFile, 18, nID, ZS_VISIBLE, 0, 0);
nY += SCANHEIGHT;
ZD_SetObjectXY(nID, nX, nY, 0);
SetObjectAnchorMode(nID, ANCHOR_CENTER);
ZD_SetObjectHidden(nID, ZS_INACTIVE); // 2 = Transparent, its ID won't be detected and it couldn't be moved.
nID = ID_DURATION;
ZD_DrawTextToCtrlEx(gP.hGDImage, L"00:00:00", 0, -1000, 0, 0, ZD_ARGB(192, 255,255,255), szFile, 18, nID, ZS_VISIBLE, 0, 0);
SetStatusTime(ToMFTIME(gB.medialength), ID_DURATION, TRUE);
ZD_GetObjectBound(nID, bmW, bmH);
nX += SCANWIDTH - bmW + 4;
ZD_SetObjectXY(nID, nX, nY, 0);
SetObjectAnchorMode(nID, ANCHOR_CENTER);
ZD_SetObjectHidden(nID, ZS_INACTIVE); // 2 = Transparent, its ID won't be detected and it couldn't be moved.
}
ZD_SetObjectZorder(ID_FLARE, ZD_ORDER_TOP);
////Use this code to save the waveform to disk
// nRet is int = API(GDImage, "ZI_SaveBitmapToFile", AnsiToUnicode(ExePath()+ fExtractPath(audiofile, fFileName)+".png"), hDIB, 0)
////if the hDIB is not used in the GDImage control, { it must be deleted with DeleteObject
// DeleteObject(hDIB)}
} |
Partager