From 2342d48be31847e7ead9d1cc682452e8f0122351 Mon Sep 17 00:00:00 2001 From: llornkcor Date: Sat, 20 Jul 2002 22:07:31 +0000 Subject: initial commit of modplugin --- (limited to 'core/multimedia/opieplayer/modplug/load_ult.cpp') diff --git a/core/multimedia/opieplayer/modplug/load_ult.cpp b/core/multimedia/opieplayer/modplug/load_ult.cpp new file mode 100644 index 0000000..c9b7118 --- a/dev/null +++ b/core/multimedia/opieplayer/modplug/load_ult.cpp @@ -0,0 +1,225 @@ +/* + * This program is free software; you can redistribute it and modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the license or (at your + * option) any later version. + * + * Authors: Olivier Lapicque +*/ + +#include "stdafx.h" +#include "sndfile.h" + +//#pragma warning(disable:4244) + +#define ULT_16BIT 0x04 +#define ULT_LOOP 0x08 +#define ULT_BIDI 0x10 + +#pragma pack(1) + +// Raw ULT header struct: +typedef struct tagULTHEADER +{ + char id[15]; // changed from CHAR + char songtitle[32]; // changed from CHAR + BYTE reserved; +} Q_PACKED ULTHEADER; + + +// Raw ULT sampleinfo struct: +typedef struct tagULTSAMPLE +{ + CHAR samplename[32]; + CHAR dosname[12]; + LONG loopstart; + LONG loopend; + LONG sizestart; + LONG sizeend; + BYTE volume; + BYTE flags; + WORD finetune; +} Q_PACKED ULTSAMPLE; + +#pragma pack() + + +BOOL CSoundFile::ReadUlt(const BYTE *lpStream, DWORD dwMemLength) +//--------------------------------------------------------------- +{ + ULTHEADER *pmh = (ULTHEADER *)lpStream; + ULTSAMPLE *pus; + UINT nos, nop; + DWORD dwMemPos = 0; + + // try to read module header + if ((!lpStream) || (dwMemLength < 0x100)) return FALSE; + if (strncmp(pmh->id,"MAS_UTrack_V00",14)) return FALSE; + // Warning! Not supported ULT format, trying anyway + // if ((pmh->id[14] < '1') || (pmh->id[14] > '4')) return FALSE; + m_nType = MOD_TYPE_ULT; + m_nDefaultSpeed = 6; + m_nDefaultTempo = 125; + memcpy(m_szNames[0], pmh->songtitle, 32); + // read songtext + dwMemPos = sizeof(ULTHEADER); + if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength)) + { + UINT len = pmh->reserved * 32; + m_lpszSongComments = new char[len + 1 + pmh->reserved]; + if (m_lpszSongComments) + { + for (UINT l=0; lreserved; l++) + { + memcpy(m_lpszSongComments+l*33, lpStream+dwMemPos+l*32, 32); + m_lpszSongComments[l*33+32] = 0x0D; + } + m_lpszSongComments[len] = 0; + } + dwMemPos += len; + } + if (dwMemPos >= dwMemLength) return TRUE; + nos = lpStream[dwMemPos++]; + m_nSamples = nos; + if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1; + UINT smpsize = 64; + if (pmh->id[14] >= '4') smpsize += 2; + if (dwMemPos + nos*smpsize + 256 + 2 > dwMemLength) return TRUE; + for (UINT ins=1; ins<=nos; ins++, dwMemPos+=smpsize) if (ins<=m_nSamples) + { + pus = (ULTSAMPLE *)(lpStream+dwMemPos); + MODINSTRUMENT *pins = &Ins[ins]; + memcpy(m_szNames[ins], pus->samplename, 32); + memcpy(pins->name, pus->dosname, 12); + pins->nLoopStart = pus->loopstart; + pins->nLoopEnd = pus->loopend; + pins->nLength = pus->sizeend - pus->sizestart; + pins->nVolume = pus->volume; + pins->nGlobalVol = 64; + pins->nC4Speed = 8363; + if (pmh->id[14] >= '4') + { + pins->nC4Speed = pus->finetune; + } + if (pus->flags & ULT_LOOP) pins->uFlags |= CHN_LOOP; + if (pus->flags & ULT_BIDI) pins->uFlags |= CHN_PINGPONGLOOP; + if (pus->flags & ULT_16BIT) + { + pins->uFlags |= CHN_16BIT; + pins->nLoopStart >>= 1; + pins->nLoopEnd >>= 1; + } + } + memcpy(Order, lpStream+dwMemPos, 256); + dwMemPos += 256; + m_nChannels = lpStream[dwMemPos] + 1; + nop = lpStream[dwMemPos+1] + 1; + dwMemPos += 2; + if (m_nChannels > 32) m_nChannels = 32; + // Default channel settings + for (UINT nSet=0; nSetid[14]>='3') + { + if (dwMemPos + m_nChannels > dwMemLength) return TRUE; + for(UINT t=0; t 256) ChnSettings[t].nPan = 256; + } + } + // Allocating Patterns + for (UINT nAllocPat=0; nAllocPat dwMemLength) return TRUE; + UINT rep = 1; + UINT note = lpStream[dwMemPos++]; + if (note == 0xFC) + { + rep = lpStream[dwMemPos]; + note = lpStream[dwMemPos+1]; + dwMemPos += 2; + } + UINT instr = lpStream[dwMemPos++]; + UINT eff = lpStream[dwMemPos++]; + UINT dat1 = lpStream[dwMemPos++]; + UINT dat2 = lpStream[dwMemPos++]; + UINT cmd1 = eff & 0x0F; + UINT cmd2 = eff >> 4; + if (cmd1 == 0x0C) dat1 >>= 2; else + if (cmd1 == 0x0B) { cmd1 = dat1 = 0; } + if (cmd2 == 0x0C) dat2 >>= 2; else + if (cmd2 == 0x0B) { cmd2 = dat2 = 0; } + while ((rep != 0) && (row < 64)) + { + if (pat) + { + pat->instr = instr; + if (note) pat->note = note + 36; + if (cmd1 | dat1) + { + if (cmd1 == 0x0C) + { + pat->volcmd = VOLCMD_VOLUME; + pat->vol = dat1; + } else + { + pat->command = cmd1; + pat->param = dat1; + ConvertModCommand(pat); + } + } + if (cmd2 == 0x0C) + { + pat->volcmd = VOLCMD_VOLUME; + pat->vol = dat2; + } else + if ((cmd2 | dat2) && (!pat->command)) + { + pat->command = cmd2; + pat->param = dat2; + ConvertModCommand(pat); + } + pat += m_nChannels; + } + row++; + rep--; + } + } + } + } + // Reading Instruments + for (UINT smp=1; smp<=m_nSamples; smp++) if (Ins[smp].nLength) + { + if (dwMemPos >= dwMemLength) return TRUE; + UINT flags = (Ins[smp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; + dwMemPos += ReadSample(&Ins[smp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos); + } + return TRUE; +} + -- cgit v0.9.0.2