summaryrefslogtreecommitdiffstats
path: root/gst/modplug/libmodplug/load_dmf.cpp
diff options
context:
space:
mode:
authorHans de Goede <jwrdegoede@fedoraproject.org>2009-01-24 18:13:39 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-01-24 18:13:39 +0100
commitbf7ccbe0f8fd834ef186e5c266e40acaadf5536d (patch)
tree155ce9c51f5cfc1cc3a43942094eb9bf3bdd6575 /gst/modplug/libmodplug/load_dmf.cpp
parent83ca36e07f7690b0703396f85974ba4ffd7a27e5 (diff)
downloadgst-plugins-bad-bf7ccbe0f8fd834ef186e5c266e40acaadf5536d.tar.gz
gst-plugins-bad-bf7ccbe0f8fd834ef186e5c266e40acaadf5536d.tar.bz2
gst-plugins-bad-bf7ccbe0f8fd834ef186e5c266e40acaadf5536d.zip
Build the modplug plugin against the modplug library and remove our copy
Always build the modplug plugin against the system modplug library and remove our own copy. Using the system version has advantages if security issues or other critical bugs are found in libmodplug and our own copy wasn't really maintained anyway. Also our copy only contained some patches to use GLib types and functions. Fixes bug #568837.
Diffstat (limited to 'gst/modplug/libmodplug/load_dmf.cpp')
-rw-r--r--gst/modplug/libmodplug/load_dmf.cpp611
1 files changed, 0 insertions, 611 deletions
diff --git a/gst/modplug/libmodplug/load_dmf.cpp b/gst/modplug/libmodplug/load_dmf.cpp
deleted file mode 100644
index f49e65a2..00000000
--- a/gst/modplug/libmodplug/load_dmf.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * This source code is public domain.
- *
- * Authors: Olivier Lapicque <olivierl@jps.net>
-*/
-
-///////////////////////////////////////////////////////
-// DMF DELUSION DIGITAL MUSIC FILEFORMAT (X-Tracker) //
-///////////////////////////////////////////////////////
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "stdafx.h"
-#include "sndfile.h"
-
-//#define DMFLOG
-
-//#pragma warning(disable:4244)
-
-#pragma pack(1)
-
-typedef struct DMFHEADER
-{
- DWORD id; // "DDMF" = 0x464d4444
- BYTE version; // 4
- CHAR trackername[8]; // "XTRACKER"
- CHAR songname[30];
- CHAR composer[20];
- BYTE date[3];
-} DMFHEADER;
-
-typedef struct DMFINFO
-{
- DWORD id; // "INFO"
- DWORD infosize;
-} DMFINFO;
-
-typedef struct DMFSEQU
-{
- DWORD id; // "SEQU"
- DWORD seqsize;
- WORD loopstart;
- WORD loopend;
- WORD sequ[2];
-} DMFSEQU;
-
-typedef struct DMFPATT
-{
- DWORD id; // "PATT"
- DWORD patsize;
- WORD numpat; // 1-1024
- BYTE tracks;
- BYTE firstpatinfo;
-} DMFPATT;
-
-typedef struct DMFTRACK
-{
- BYTE tracks;
- BYTE beat; // [hi|lo] -> hi=ticks per beat, lo=beats per measure
- WORD ticks; // max 512
- DWORD jmpsize;
-} DMFTRACK;
-
-typedef struct DMFSMPI
-{
- DWORD id;
- DWORD size;
- BYTE samples;
-} DMFSMPI;
-
-typedef struct DMFSAMPLE
-{
- DWORD len;
- DWORD loopstart;
- DWORD loopend;
- WORD c3speed;
- BYTE volume;
- BYTE flags;
-} DMFSAMPLE;
-
-#pragma pack()
-
-
-#ifdef DMFLOG
-extern void Log(LPCSTR s, ...);
-#endif
-
-
-BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
-//---------------------------------------------------------------
-{
- DMFHEADER *pfh = (DMFHEADER *)lpStream;
- DMFINFO *psi;
- DMFSEQU *sequ;
- DWORD dwMemPos;
- BYTE infobyte[32];
- BYTE smplflags[MAX_SAMPLES];
-
- if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
- if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return FALSE;
- dwMemPos = 66;
- memcpy(m_szNames[0], pfh->songname, 30);
- m_szNames[0][30] = 0;
- m_nType = MOD_TYPE_DMF;
- m_nChannels = 0;
-#ifdef DMFLOG
- Log("DMF version %d: \"%s\": %d bytes (0x%04X)\n", pfh->version, m_szNames[0], dwMemLength, dwMemLength);
-#endif
- while (dwMemPos + 7 < dwMemLength)
- {
- DWORD id = *((LPDWORD)(lpStream+dwMemPos));
-
- switch(id)
- {
- // "INFO"
- case 0x4f464e49:
- // "CMSG"
- case 0x47534d43:
- psi = (DMFINFO *)(lpStream+dwMemPos);
- if (id == 0x47534d43) dwMemPos++;
- if ((psi->infosize > dwMemLength) || (psi->infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
- if ((psi->infosize >= 8) && (!m_lpszSongComments))
- {
- m_lpszSongComments = new char[psi->infosize]; // changed from CHAR
- if (m_lpszSongComments)
- {
- for (UINT i=0; i<psi->infosize-1; i++)
- {
- CHAR c = lpStream[dwMemPos+8+i];
- if ((i % 40) == 39)
- m_lpszSongComments[i] = 0x0d;
- else
- m_lpszSongComments[i] = (c < ' ') ? ' ' : c;
- }
- m_lpszSongComments[psi->infosize-1] = 0;
- }
- }
- dwMemPos += psi->infosize + 8 - 1;
- break;
-
- // "SEQU"
- case 0x55514553:
- sequ = (DMFSEQU *)(lpStream+dwMemPos);
- if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
- {
- UINT nseq = sequ->seqsize >> 1;
- if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
- if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart;
- for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i];
- }
- dwMemPos += sequ->seqsize + 8;
- break;
-
- // "PATT"
- case 0x54544150:
- if (!m_nChannels)
- {
- DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
- UINT numpat;
- DWORD dwPos = dwMemPos + 11;
- if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
- numpat = patt->numpat;
- if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
- m_nChannels = patt->tracks;
- if (m_nChannels < patt->firstpatinfo) m_nChannels = patt->firstpatinfo;
- if (m_nChannels > 32) m_nChannels = 32;
- if (m_nChannels < 4) m_nChannels = 4;
- for (UINT npat=0; npat<numpat; npat++)
- {
- DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
- #ifdef DMFLOG
- Log("Pattern #%d: %d tracks, %d rows\n", npat, pt->tracks, pt->ticks);
- #endif
- UINT tracks = pt->tracks;
- if (tracks > 32) tracks = 32;
- UINT ticks = pt->ticks;
- if (ticks > 256) ticks = 256;
- if (ticks < 16) ticks = 16;
- dwPos += 8;
- if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
- PatternSize[npat] = (WORD)ticks;
- MODCOMMAND *m = AllocatePattern(PatternSize[npat], m_nChannels);
- if (!m) goto dmfexit;
- Patterns[npat] = m;
- DWORD d = dwPos;
- dwPos += pt->jmpsize;
- UINT ttype = 1;
- UINT tempo = 125;
- UINT glbinfobyte = 0;
- UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
- BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
- memset(infobyte, 0, sizeof(infobyte));
- for (UINT row=0; row<ticks; row++)
- {
- MODCOMMAND *p = &m[row*m_nChannels];
- // Parse track global effects
- if (!glbinfobyte)
- {
- BYTE info = lpStream[d++];
- BYTE infoval = 0;
- if ((info & 0x80) && (d < dwPos)) glbinfobyte = lpStream[d++];
- info &= 0x7f;
- if ((info) && (d < dwPos)) infoval = lpStream[d++];
- switch(info)
- {
- case 1: ttype = 0; tempo = infoval; tempochange = TRUE; break;
- case 2: ttype = 1; tempo = infoval; tempochange = TRUE; break;
- case 3: pbeat = infoval>>4; tempochange = ttype; break;
- #ifdef DMFLOG
- default: if (info) Log("GLB: %02X.%02X\n", info, infoval);
- #endif
- }
- } else
- {
- glbinfobyte--;
- }
- // Parse channels
- for (UINT i=0; i<tracks; i++) if (!infobyte[i])
- {
- MODCOMMAND cmd = {0,0,0,0,0,0};
- BYTE info = lpStream[d++];
- if (info & 0x80) infobyte[i] = lpStream[d++];
- // Instrument
- if (info & 0x40)
- {
- cmd.instr = lpStream[d++];
- }
- // Note
- if (info & 0x20)
- {
- cmd.note = lpStream[d++];
- if ((cmd.note) && (cmd.note < 0xfe)) cmd.note &= 0x7f;
- if ((cmd.note) && (cmd.note < 128)) cmd.note += 24;
- }
- // Volume
- if (info & 0x10)
- {
- cmd.volcmd = VOLCMD_VOLUME;
- cmd.vol = (lpStream[d++]+3)>>2;
- }
- // Effect 1
- if (info & 0x08)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Key Off
- case 1: if (!cmd.note) cmd.note = 0xFE; break;
- // 2: Set Loop
- // 4: Sample Delay
- case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
- // 5: Retrig
- case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
- // 6: Offset
- case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
- #ifdef DMFLOG
- default: Log("FX1: %02X.%02X\n", efx, eval);
- #endif
- }
- }
- // Effect 2
- if (info & 0x04)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Finetune
- case 1: if (eval&0xf0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>4)|0x20; } break;
- // 2: Note Delay
- case 2: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
- // 3: Arpeggio
- case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
- // 4: Portamento Up
- case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
- // 5: Portamento Down
- case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
- // 6: Tone Portamento
- case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = eval; break;
- // 8: Vibrato
- case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
- // 12: Note cut
- case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
- else if (!cmd.note) { cmd.note = 0xfe; } break;
- #ifdef DMFLOG
- default: Log("FX2: %02X.%02X\n", efx, eval);
- #endif
- }
- }
- // Effect 3
- if (info & 0x02)
- {
- BYTE efx = lpStream[d++];
- BYTE eval = lpStream[d++];
- switch(efx)
- {
- // 1: Vol Slide Up
- case 1: if (eval == 0xff) break;
- eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_VOLUMESLIDE; cmd.param = eval<<4; break;
- // 2: Vol Slide Down
- case 2: if (eval == 0xff) break;
- eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
- // 7: Set Pan
- case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
- else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
- // 8: Pan Slide Left
- case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_PANNINGSLIDE; cmd.param = eval<<4; break;
- // 9: Pan Slide Right
- case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
- cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
- #ifdef DMFLOG
- default: Log("FX3: %02X.%02X\n", efx, eval);
- #endif
-
- }
- }
- // Store effect
- if (i < m_nChannels) p[i] = cmd;
- if (d > dwPos)
- {
- #ifdef DMFLOG
- Log("Unexpected EOP: row=%d\n", row);
- #endif
- break;
- }
- } else
- {
- infobyte[i]--;
- }
-
- // Find free channel for tempo change
- if (tempochange)
- {
- tempochange = FALSE;
- UINT speed=6, modtempo=tempo;
- UINT rpm = ((ttype) && (pbeat)) ? tempo*pbeat : (tempo+1)*15;
- for (speed=30; speed>1; speed--)
- {
- modtempo = rpm*speed/24;
- if (modtempo <= 200) break;
- if ((speed < 6) && (modtempo < 256)) break;
- }
- #ifdef DMFLOG
- Log("Tempo change: ttype=%d pbeat=%d tempo=%3d -> speed=%d tempo=%d\n",
- ttype, pbeat, tempo, speed, modtempo);
- #endif
- for (UINT ich=0; ich<m_nChannels; ich++) if (!p[ich].command)
- {
- if (speed)
- {
- p[ich].command = CMD_SPEED;
- p[ich].param = (BYTE)speed;
- speed = 0;
- } else
- if ((modtempo >= 32) && (modtempo < 256))
- {
- p[ich].command = CMD_TEMPO;
- p[ich].param = (BYTE)modtempo;
- modtempo = 0;
- } else
- {
- break;
- }
- }
- }
- if (d >= dwPos) break;
- }
- #ifdef DMFLOG
- Log(" %d/%d bytes remaining\n", dwPos-d, pt->jmpsize);
- #endif
- if (dwPos + 8 >= dwMemLength) break;
- }
- dwMemPos += patt->patsize + 8;
- }
- break;
-
- // "SMPI": Sample Info
- case 0x49504d53:
- {
- DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
- if (pds->size <= dwMemLength - dwMemPos)
- {
- DWORD dwPos = dwMemPos + 9;
- m_nSamples = pds->samples;
- if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
- for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
- {
- UINT namelen = lpStream[dwPos];
- smplflags[iSmp] = 0;
- if (dwPos+namelen+1+sizeof(DMFSAMPLE) > dwMemPos+pds->size+8) break;
- if (namelen)
- {
- UINT rlen = (namelen < 32) ? namelen : 31;
- memcpy(m_szNames[iSmp], lpStream+dwPos+1, rlen);
- m_szNames[iSmp][rlen] = 0;
- }
- dwPos += namelen + 1;
- DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
- MODINSTRUMENT *psmp = &Ins[iSmp];
- psmp->nLength = psh->len;
- psmp->nLoopStart = psh->loopstart;
- psmp->nLoopEnd = psh->loopend;
- psmp->nC4Speed = psh->c3speed;
- psmp->nGlobalVol = 64;
- psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
- psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
- if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
- if (psh->flags & 1) psmp->uFlags |= CHN_LOOP;
- smplflags[iSmp] = psh->flags;
- dwPos += (pfh->version < 8) ? 22 : 30;
- #ifdef DMFLOG
- Log("SMPI %d/%d: len=%d flags=0x%02X\n", iSmp, m_nSamples, psmp->nLength, psh->flags);
- #endif
- }
- }
- dwMemPos += pds->size + 8;
- }
- break;
-
- // "SMPD": Sample Data
- case 0x44504d53:
- {
- DWORD dwPos = dwMemPos + 8;
- UINT ismpd = 0;
- for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
- {
- ismpd++;
- DWORD pksize;
- if (dwPos + 4 >= dwMemLength)
- {
- #ifdef DMFLOG
- Log("Unexpected EOF at sample %d/%d! (pos=%d)\n", iSmp, m_nSamples, dwPos);
- #endif
- break;
- }
- pksize = *((LPDWORD)(lpStream+dwPos));
- #ifdef DMFLOG
- Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize);
- Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4)));
- #endif
- dwPos += 4;
- if (pksize > dwMemLength - dwPos)
- {
- #ifdef DMFLOG
- Log("WARNING: pksize=%d, but only %d bytes left\n", pksize, dwMemLength-dwPos);
- #endif
- pksize = dwMemLength - dwPos;
- }
- if ((pksize) && (iSmp <= m_nSamples))
- {
- UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
- if (smplflags[ismpd] & 4) flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
- ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwPos), pksize);
- }
- dwPos += pksize;
- }
- dwMemPos = dwPos;
- }
- break;
-
- // "ENDE": end of file
- case 0x45444e45:
- goto dmfexit;
-
- // Unrecognized id, or "ENDE" field
- default:
- dwMemPos += 4;
- break;
- }
- }
-dmfexit:
- if (!m_nChannels)
- {
- if (!m_nSamples)
- {
- m_nType = MOD_TYPE_NONE;
- return FALSE;
- }
- m_nChannels = 4;
- }
- return TRUE;
-}
-
-
-///////////////////////////////////////////////////////////////////////
-// DMF Compression
-
-#pragma pack(1)
-
-typedef struct DMF_HNODE
-{
- short int left, right;
- BYTE value;
-} DMF_HNODE;
-
-typedef struct DMF_HTREE
-{
- LPBYTE ibuf, ibufmax;
- DWORD bitbuf;
- UINT bitnum;
- UINT lastnode, nodecount;
- DMF_HNODE nodes[256];
-} DMF_HTREE;
-
-#pragma pack()
-
-
-// DMF Huffman ReadBits
-BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
-//-------------------------------------------
-{
- BYTE x = 0, bitv = 1;
- while (nbits--)
- {
- if (tree->bitnum)
- {
- tree->bitnum--;
- } else
- {
- tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
- tree->bitnum = 7;
- }
- if (tree->bitbuf & 1) x |= bitv;
- bitv <<= 1;
- tree->bitbuf >>= 1;
- }
- return x;
-}
-
-//
-// tree: [8-bit value][12-bit index][12-bit index] = 32-bit
-//
-
-void DMFNewNode(DMF_HTREE *tree)
-//------------------------------
-{
- BYTE isleft, isright;
- UINT actnode;
-
- actnode = tree->nodecount;
- if (actnode > 255) return;
- tree->nodes[actnode].value = DMFReadBits(tree, 7);
- isleft = DMFReadBits(tree, 1);
- isright = DMFReadBits(tree, 1);
- actnode = tree->lastnode;
- if (actnode > 255) return;
- tree->nodecount++;
- tree->lastnode = tree->nodecount;
- if (isleft)
- {
- tree->nodes[actnode].left = tree->lastnode;
- DMFNewNode(tree);
- } else
- {
- tree->nodes[actnode].left = -1;
- }
- tree->lastnode = tree->nodecount;
- if (isright)
- {
- tree->nodes[actnode].right = tree->lastnode;
- DMFNewNode(tree);
- } else
- {
- tree->nodes[actnode].right = -1;
- }
-}
-
-
-int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
-//----------------------------------------------------------------------
-{
- DMF_HTREE tree;
- UINT actnode;
- BYTE value, sign, delta = 0;
-
- memset(&tree, 0, sizeof(tree));
- tree.ibuf = ibuf;
- tree.ibufmax = ibufmax;
- DMFNewNode(&tree);
- value = 0;
- for (UINT i=0; i<maxlen; i++)
- {
- actnode = 0;
- sign = DMFReadBits(&tree, 1);
- do
- {
- if (DMFReadBits(&tree, 1))
- actnode = tree.nodes[actnode].right;
- else
- actnode = tree.nodes[actnode].left;
- if (actnode > 255) break;
- delta = tree.nodes[actnode].value;
- if ((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
- } while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
- if (sign) delta ^= 0xFF;
- value += delta;
- psample[i] = (i) ? value : 0;
- }
-#ifdef DMFLOG
-// Log("DMFUnpack: %d remaining bytes\n", tree.ibufmax-tree.ibuf);
-#endif
- return tree.ibuf - ibuf;
-}
-
-