mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-24 18:56:33 +00:00
TONY: Remove custom sound CODEC classes
We already have our own raw PCM and IMA ADPCM classes that we will use
This commit is contained in:
parent
9b3df4de21
commit
05340fa4ca
@ -37,693 +37,8 @@ namespace Tony {
|
||||
* Defines
|
||||
\****************************************************************************/
|
||||
|
||||
/* Massimo numero di bytes da decodificare in una singola chiamata a CODEC */
|
||||
#define MAXDECODESIZE (44100 * 2 * 2)
|
||||
|
||||
#define RELEASE(x) {if ((x) != NULL) { (x)->Release(); x = NULL; }}
|
||||
|
||||
/****************************************************************************\
|
||||
*****************************************************************************
|
||||
* class CODEC (ABSTRACT)
|
||||
* -----------
|
||||
* Description: classe base per CODEC.
|
||||
*****************************************************************************
|
||||
\****************************************************************************/
|
||||
|
||||
class CODEC {
|
||||
protected:
|
||||
bool bEndReached;
|
||||
|
||||
public:
|
||||
bool bLoop;
|
||||
CODEC(bool bLoop = true);
|
||||
virtual ~CODEC();
|
||||
virtual uint32 Decompress(HANDLE hStream, void *lpBuf, uint32 dwSize) = 0;
|
||||
virtual uint32 Decompress(Common::File &fp, void *lpBuf, uint32 dwSize) = 0;
|
||||
virtual void LoopReset() = 0;
|
||||
bool EndOfStream();
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
*****************************************************************************
|
||||
* class CODECRAW
|
||||
* --------------
|
||||
* Description: CODEC di play da disco di campioni puri
|
||||
*****************************************************************************
|
||||
\****************************************************************************/
|
||||
|
||||
class CODECRAW : public CODEC {
|
||||
public:
|
||||
CODECRAW(bool bLoop = true);
|
||||
virtual ~CODECRAW();
|
||||
virtual uint32 Decompress(HANDLE hStream, void *lpBuf, uint32 dwSize);
|
||||
virtual uint32 Decompress(Common::File &fp, void *lpBuf, uint32 dwSize);
|
||||
virtual void LoopReset();
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
*****************************************************************************
|
||||
* class CODECADPCM
|
||||
* ----------------
|
||||
* Description: CODEC per play di compressione ADPCM
|
||||
*****************************************************************************
|
||||
\****************************************************************************/
|
||||
|
||||
class CODECADPCM : public CODECRAW {
|
||||
protected:
|
||||
byte *lpTemp;
|
||||
static const int indexTable[16];
|
||||
static const int stepSizeTable[89];
|
||||
|
||||
public:
|
||||
CODECADPCM(bool bLoop = true, byte *lpTempBuffer = NULL);
|
||||
virtual ~CODECADPCM();
|
||||
virtual uint32 Decompress(HANDLE hStream, void *lpBuf, uint32 dwSize) = 0;
|
||||
virtual uint32 Decompress(Common::File &fp, void *lpBuf, uint32 dwSize) = 0;
|
||||
virtual void LoopReset() = 0;
|
||||
};
|
||||
|
||||
class CODECADPCMSTEREO : public CODECADPCM {
|
||||
protected:
|
||||
int valpred[2], index[2];
|
||||
|
||||
public:
|
||||
CODECADPCMSTEREO(bool bLoop = true, byte *lpTempBuffer = NULL);
|
||||
virtual ~CODECADPCMSTEREO();
|
||||
virtual uint32 Decompress(HANDLE hStream, void *lpBuf, uint32 dwSize);
|
||||
virtual uint32 Decompress(Common::File &fp, void *lpBuf, uint32 dwSize);
|
||||
virtual void LoopReset();
|
||||
};
|
||||
|
||||
class CODECADPCMMONO : public CODECADPCM {
|
||||
protected:
|
||||
int valpred, index;
|
||||
|
||||
public:
|
||||
CODECADPCMMONO(bool bLoop = true, byte *lpTempBuffer = NULL);
|
||||
virtual ~CODECADPCMMONO();
|
||||
virtual uint32 Decompress(HANDLE hStream, void *lpBuf, uint32 dwSize);
|
||||
virtual uint32 Decompress(Common::File &fp, void *lpBuf, uint32 dwSize);
|
||||
virtual void LoopReset();
|
||||
};
|
||||
|
||||
/****************************************************************************\
|
||||
* Metodi per CODEC
|
||||
\****************************************************************************/
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODEC::CODEC(bool loop = true);
|
||||
*
|
||||
* Description: Costruttore standard. E' possibile specificare se si vuole
|
||||
* attivare o disattivare il loop (che di default e' attivo).
|
||||
*
|
||||
* Input: bool loop true se si vuole attivare il loop,
|
||||
* false per disattivarlo
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
CODEC::CODEC(bool loop) {
|
||||
bLoop = loop;
|
||||
bEndReached = false;
|
||||
}
|
||||
|
||||
CODEC::~CODEC() {
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: bool CODEC::EndOfStream()
|
||||
*
|
||||
* Description: Informa se abbiamo raggiunto la fine dello stream
|
||||
*
|
||||
* Return: true se siamo arrivati alla fine, false altrimenti
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
bool CODEC::EndOfStream() {
|
||||
return bEndReached;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
* Metodi per CODECRAW
|
||||
\****************************************************************************/
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECRAW::CODECRAW(bool loop = true);
|
||||
*
|
||||
* Description: Costruttore standard. Richiama solamente il costruttore della
|
||||
* classe astratta CODEC.
|
||||
*
|
||||
* Input: bool loop true se si vuole attivare il loop,
|
||||
* false per disattivarlo
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
CODECRAW::CODECRAW(bool loop) : CODEC(loop) {
|
||||
}
|
||||
|
||||
CODECRAW::~CODECRAW() {
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECRAW::LoopReset();
|
||||
*
|
||||
* Description: Resetta il playing prima di iniziare di nuovo il file.
|
||||
* Nel caso dei file RAW non fa nulla.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
void CODECRAW::LoopReset() {
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: uint32 CODECRAW::Decompress(HANDLE hStream, void *lpBuf,
|
||||
* uint32 dwSize)
|
||||
*
|
||||
* Description: Gestisce il formato RAW: semplicemente copia dal file
|
||||
* stream nel buffer.
|
||||
*
|
||||
* Return: Se e' stata raggiunta la fine del file, indica quale byte,
|
||||
* tra quelli letti, e' l'inizio del nuovo loop. Altrimenti
|
||||
* il valore non e' determinato.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
uint32 CODECRAW::Decompress(HANDLE hStream, void *buf, uint32 dwSize) {
|
||||
#if 0
|
||||
byte *lpBuf = (byte *)buf;
|
||||
uint32 dwRead;
|
||||
uint32 dwEOF;
|
||||
|
||||
bEndReached = false;
|
||||
dwEOF = 0;
|
||||
ReadFile(hStream, lpBuf, dwSize, &dwRead, NULL);
|
||||
|
||||
if (dwRead < dwSize) {
|
||||
dwEOF = dwRead;
|
||||
bEndReached = true;
|
||||
|
||||
if (!bLoop) {
|
||||
ZeroMemory(lpBuf + dwRead, dwSize - dwRead);
|
||||
} else {
|
||||
SetFilePointer(hStream, 0, NULL, FILE_BEGIN);
|
||||
ReadFile(hStream, lpBuf + dwRead, dwSize - dwRead, &dwRead, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return dwEOF;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CODECRAW::Decompress(Common::File &fp, void *buf, uint32 dwSize) {
|
||||
byte *lpBuf = (byte *)buf;
|
||||
uint32 dwRead;
|
||||
uint32 dwEOF;
|
||||
|
||||
bEndReached = false;
|
||||
dwEOF = 0;
|
||||
|
||||
dwRead = fp.read(lpBuf, dwSize);
|
||||
|
||||
if (dwRead < dwSize) {
|
||||
dwEOF = dwRead;
|
||||
bEndReached = true;
|
||||
|
||||
if (!bLoop) {
|
||||
Common::fill(lpBuf + dwRead, lpBuf + dwRead + (dwSize - dwRead), 0);
|
||||
} else {
|
||||
fp.seek(0);
|
||||
fp.read(lpBuf + dwRead, dwSize - dwRead);
|
||||
}
|
||||
}
|
||||
|
||||
return dwEOF;
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
* Metodi per CODECADPCM
|
||||
\****************************************************************************/
|
||||
|
||||
const int CODECADPCM::indexTable[16] = {
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
};
|
||||
|
||||
const int CODECADPCM::stepSizeTable[89] = {
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
|
||||
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
|
||||
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
|
||||
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
|
||||
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
|
||||
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
|
||||
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
|
||||
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
||||
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECADPCM::CODECADPCM()
|
||||
*
|
||||
* Description: Costruttore. Inizializza le tabelle e alloca la memoria
|
||||
* temporanea.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
CODECADPCM::CODECADPCM(bool loop, byte *lpTempBuffer) : CODECRAW(loop) {
|
||||
/* Alloca la memoria temporanea */
|
||||
if (lpTempBuffer != NULL) {
|
||||
lpTemp = lpTempBuffer;
|
||||
} else {
|
||||
lpTemp = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT, MAXDECODESIZE);
|
||||
|
||||
if (lpTemp == NULL) {
|
||||
error("Insufficient memory!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CODECADPCMMONO::CODECADPCMMONO(bool loop, byte *lpTempBuffer) : CODECADPCM(loop, lpTempBuffer) {
|
||||
/* Inizializza per il playing */
|
||||
LoopReset();
|
||||
}
|
||||
|
||||
CODECADPCMMONO::~CODECADPCMMONO() {
|
||||
}
|
||||
|
||||
|
||||
CODECADPCMSTEREO::CODECADPCMSTEREO(bool loop, byte *lpTempBuffer) : CODECADPCM(loop, lpTempBuffer) {
|
||||
/* Inizializza per il playing */
|
||||
LoopReset();
|
||||
}
|
||||
|
||||
CODECADPCMSTEREO::~CODECADPCMSTEREO() {
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECADPCM::~CODECADPCM()
|
||||
*
|
||||
* Description: Distruttore. Libera la memoria temporanea.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
CODECADPCM::~CODECADPCM() {
|
||||
globalFree(lpTemp);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECADPCM::LoopReset()
|
||||
*
|
||||
* Description: Resetta il player prima di ogni play o loop.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
void CODECADPCMSTEREO::LoopReset() {
|
||||
valpred[0] = 0;
|
||||
valpred[1] = 0;
|
||||
index[0] = 0;
|
||||
index[1] = 0;
|
||||
}
|
||||
|
||||
void CODECADPCMMONO::LoopReset() {
|
||||
valpred = 0;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************\
|
||||
*
|
||||
* Function: CODECADPCM::Decompress(HANDLE hStream, void *lpBuf,
|
||||
* uint32 dwSize);
|
||||
*
|
||||
* Description: Gestisce il formato ADPCM 16:4. La routine dovrebbe essere
|
||||
* ottimizzata in Assembler per garantire migliori performance.
|
||||
*
|
||||
\****************************************************************************/
|
||||
|
||||
uint32 CODECADPCMMONO::Decompress(HANDLE hFile, void *buf, uint32 dwSize) {
|
||||
#if 0
|
||||
uint16 *lpBuf = (uint16 *)buf;
|
||||
byte *inp;
|
||||
int bufferstep;
|
||||
int cache;
|
||||
int delta;
|
||||
int sign;
|
||||
int vpdiff;
|
||||
uint32 eof, i;
|
||||
int step;
|
||||
uint32 dwRead;
|
||||
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
|
||||
/* Richiama il CODEC RAW per leggere da disco lo stream con loop. La
|
||||
chiamata e' possibile perche' abbiamo ereditato CODECADPCM da CODECRAW,
|
||||
e non semplicemente da CODEC. */
|
||||
eof = CODECRAW::Decompress(hFile, lpTemp, dwSize / 4);
|
||||
inp = lpTemp;
|
||||
|
||||
eof *= 2;
|
||||
/* Se bisogna loopare subito lo fa */
|
||||
if (EndOfStream() && eof == 0) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
} else if (!EndOfStream())
|
||||
eof = 0;
|
||||
|
||||
dwSize /= 2;
|
||||
for (i = 0; i < dwSize; i++) {
|
||||
/* Controlla se siamo alla fine del file, e bisogna loopare */
|
||||
if (eof != 0 && i == eof) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
}
|
||||
|
||||
/* Legge il delta (4 bit) */
|
||||
if (bufferstep) {
|
||||
cache = *inp++;
|
||||
delta = (cache >> 4) & 0xF;
|
||||
} else
|
||||
delta = cache & 0xF;
|
||||
|
||||
/* Trova il nuovo indice */
|
||||
index += indexTable[delta];
|
||||
if (index < 0) index = 0;
|
||||
if (index > 88) index = 88;
|
||||
|
||||
/* Legge il segno e lo separa dall'ampliamento */
|
||||
sign = delta & 8;
|
||||
delta = delta & 7;
|
||||
|
||||
/* Trova la differenza dal valore precedente */
|
||||
vpdiff = step >> 3;
|
||||
if (delta & 4) vpdiff += step;
|
||||
if (delta & 2) vpdiff += step >> 1;
|
||||
if (delta & 1) vpdiff += step >> 2;
|
||||
|
||||
if (sign)
|
||||
valpred -= vpdiff;
|
||||
else
|
||||
valpred += vpdiff;
|
||||
|
||||
/* Controlla i limiti del valore trovato */
|
||||
if (valpred > 32767)
|
||||
valpred = 32767;
|
||||
else if (valpred < -32768)
|
||||
valpred = -32768;
|
||||
|
||||
/* Aggiorna lo step */
|
||||
step = stepSizeTable[index];
|
||||
|
||||
/* Scrive il valore trovato */
|
||||
*lpBuf++ = (signed short)valpred;
|
||||
|
||||
bufferstep = !bufferstep;
|
||||
}
|
||||
|
||||
return eof / 2;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CODECADPCMMONO::Decompress(Common::File &fp, void *buf, uint32 dwSize) {
|
||||
uint16 *lpBuf = (uint16 *)buf;
|
||||
byte *inp;
|
||||
int bufferstep;
|
||||
int cache = 0;
|
||||
int delta;
|
||||
int sign;
|
||||
int vpdiff;
|
||||
uint32 eof, i;
|
||||
int step;
|
||||
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
|
||||
/* Richiama il CODEC RAW per leggere da disco lo stream con loop. La
|
||||
chiamata e' possibile perche' abbiamo ereditato CODECADPCM da CODECRAW,
|
||||
e non semplicemente da CODEC. */
|
||||
eof = CODECRAW::Decompress(fp, lpTemp, dwSize / 4);
|
||||
inp = lpTemp;
|
||||
|
||||
eof *= 2;
|
||||
|
||||
/* Se bisogna loopare subito lo fa */
|
||||
if (EndOfStream() && eof == 0) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
} else if (!EndOfStream())
|
||||
eof = 0;
|
||||
|
||||
dwSize /= 2;
|
||||
for (i = 0; i < dwSize; i++) {
|
||||
/* Controlla se siamo alla fine del file, e bisogna loopare */
|
||||
if (eof != 0 && i == eof) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step = stepSizeTable[index];
|
||||
}
|
||||
|
||||
/* Legge il delta (4 bit) */
|
||||
if (bufferstep) {
|
||||
cache = *inp++;
|
||||
delta = (cache >> 4) & 0xF;
|
||||
} else
|
||||
delta = cache & 0xF;
|
||||
|
||||
/* Trova il nuovo indice */
|
||||
index += indexTable[delta];
|
||||
if (index < 0) index = 0;
|
||||
if (index > 88) index = 88;
|
||||
|
||||
/* Legge il segno e lo separa dall'ampliamento */
|
||||
sign = delta & 8;
|
||||
delta = delta & 7;
|
||||
|
||||
/* Trova la differenza dal valore precedente */
|
||||
vpdiff = step >> 3;
|
||||
if (delta & 4) vpdiff += step;
|
||||
if (delta & 2) vpdiff += step >> 1;
|
||||
if (delta & 1) vpdiff += step >> 2;
|
||||
|
||||
if (sign)
|
||||
valpred -= vpdiff;
|
||||
else
|
||||
valpred += vpdiff;
|
||||
|
||||
/* Controlla i limiti del valore trovato */
|
||||
if (valpred > 32767)
|
||||
valpred = 32767;
|
||||
else if (valpred < -32768)
|
||||
valpred = - 32768;
|
||||
|
||||
/* Aggiorna lo step */
|
||||
step = stepSizeTable[index];
|
||||
|
||||
/* Scrive il valore trovato */
|
||||
*lpBuf ++ = (signed short)valpred;
|
||||
|
||||
bufferstep = !bufferstep;
|
||||
}
|
||||
|
||||
return eof / 2;
|
||||
}
|
||||
|
||||
uint32 CODECADPCMSTEREO::Decompress(HANDLE hFile, void *buf, uint32 dwSize) {
|
||||
uint16 *lpBuf = (uint16 *)buf;
|
||||
byte *inp;
|
||||
int bufferstep;
|
||||
int cache = 0;
|
||||
int delta;
|
||||
int sign;
|
||||
int vpdiff;
|
||||
uint32 eof, i;
|
||||
int step[2];
|
||||
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
|
||||
/* Richiama il CODEC RAW per leggere da disco lo stream con loop. La
|
||||
chiamata e' possibile perche' abbiamo ereditato CODECADPCM da CODECRAW,
|
||||
e non semplicemente da CODEC. */
|
||||
eof = CODECRAW::Decompress(hFile, lpTemp, dwSize / 4);
|
||||
inp = lpTemp;
|
||||
|
||||
eof *= 2;
|
||||
|
||||
/* Se bisogna loopare subito lo fa */
|
||||
if (EndOfStream() && eof == 0) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
} else if (!EndOfStream())
|
||||
eof = 0;
|
||||
|
||||
dwSize /= 2;
|
||||
for (i = 0; i < dwSize; i++) {
|
||||
/* Controlla se siamo alla fine del file, e bisogna loopare */
|
||||
if (eof != 0 && i == eof) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
}
|
||||
|
||||
/* Legge il delta (4 bit) */
|
||||
if (bufferstep) {
|
||||
cache = *inp++;
|
||||
delta = cache & 0xF;
|
||||
} else
|
||||
delta = (cache >> 4) & 0xF;
|
||||
|
||||
/* Trova il nuovo indice */
|
||||
index[bufferstep] += indexTable[delta];
|
||||
if (index[bufferstep] < 0) index[bufferstep] = 0;
|
||||
if (index[bufferstep] > 88) index[bufferstep] = 88;
|
||||
|
||||
/* Legge il segno e lo separa dall'ampliamento */
|
||||
sign = delta & 8;
|
||||
delta = delta & 7;
|
||||
|
||||
/* Trova la differenza dal valore precedente */
|
||||
vpdiff = step[bufferstep] >> 3;
|
||||
if (delta & 4) vpdiff += step[bufferstep];
|
||||
if (delta & 2) vpdiff += step[bufferstep] >> 1;
|
||||
if (delta & 1) vpdiff += step[bufferstep] >> 2;
|
||||
|
||||
if (sign)
|
||||
valpred[bufferstep] -= vpdiff;
|
||||
else
|
||||
valpred[bufferstep] += vpdiff;
|
||||
|
||||
/* Controlla i limiti del valore trovato */
|
||||
if (valpred[bufferstep] > 32767)
|
||||
valpred[bufferstep] = 32767;
|
||||
else if (valpred[bufferstep] < -32768)
|
||||
valpred[bufferstep] = -32768;
|
||||
|
||||
/* Aggiorna lo step */
|
||||
step[bufferstep] = stepSizeTable[index[bufferstep]];
|
||||
|
||||
/* Scrive il valore trovato */
|
||||
*lpBuf ++ = (signed short)valpred[bufferstep];
|
||||
|
||||
bufferstep = !bufferstep;
|
||||
}
|
||||
|
||||
return eof / 2;
|
||||
}
|
||||
|
||||
|
||||
uint32 CODECADPCMSTEREO::Decompress(Common::File &fp, void *buf, uint32 dwSize) {
|
||||
uint16 *lpBuf = (uint16 *)buf;
|
||||
byte *inp;
|
||||
int bufferstep;
|
||||
int cache = 0;
|
||||
int delta;
|
||||
int sign;
|
||||
int vpdiff;
|
||||
uint32 eof, i;
|
||||
int step[2];
|
||||
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
|
||||
/* Richiama il CODEC RAW per leggere da disco lo stream con loop. La
|
||||
chiamata e' possibile perche' abbiamo ereditato CODECADPCM da CODECRAW,
|
||||
e non semplicemente da CODEC. */
|
||||
eof = CODECRAW::Decompress(fp, lpTemp, dwSize / 4);
|
||||
inp = lpTemp;
|
||||
|
||||
eof *= 2;
|
||||
/* Se bisogna loopare subito lo fa */
|
||||
if (EndOfStream() && eof == 0) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
} else if (!EndOfStream())
|
||||
eof = 0;
|
||||
|
||||
dwSize /= 2;
|
||||
for (i = 0; i < dwSize; i++) {
|
||||
/* Controlla se siamo alla fine del file, e bisogna loopare */
|
||||
if (eof != 0 && i == eof) {
|
||||
LoopReset();
|
||||
bufferstep = 1;
|
||||
step[0] = stepSizeTable[index[0]];
|
||||
step[1] = stepSizeTable[index[1]];
|
||||
}
|
||||
|
||||
/* Legge il delta (4 bit) */
|
||||
if (bufferstep) {
|
||||
cache = *inp++;
|
||||
delta = cache & 0xF;
|
||||
} else
|
||||
delta = (cache >> 4) & 0xF;
|
||||
|
||||
/* Trova il nuovo indice */
|
||||
index[bufferstep] += indexTable[delta];
|
||||
if (index[bufferstep] < 0) index[bufferstep] = 0;
|
||||
if (index[bufferstep] > 88) index[bufferstep] = 88;
|
||||
|
||||
/* Legge il segno e lo separa dall'ampliamento */
|
||||
sign = delta & 8;
|
||||
delta = delta & 7;
|
||||
|
||||
/* Trova la differenza dal valore precedente */
|
||||
vpdiff = step[bufferstep] >> 3;
|
||||
if (delta & 4) vpdiff += step[bufferstep];
|
||||
if (delta & 2) vpdiff += step[bufferstep] >> 1;
|
||||
if (delta & 1) vpdiff += step[bufferstep] >> 2;
|
||||
|
||||
if (sign)
|
||||
valpred[bufferstep] -= vpdiff;
|
||||
else
|
||||
valpred[bufferstep] += vpdiff;
|
||||
|
||||
/* Controlla i limiti del valore trovato */
|
||||
if (valpred[bufferstep] > 32767)
|
||||
valpred[bufferstep] = 32767;
|
||||
else if (valpred[bufferstep] < -32768)
|
||||
valpred[bufferstep] = -32768;
|
||||
|
||||
/* Aggiorna lo step */
|
||||
step[bufferstep] = stepSizeTable[index[bufferstep]];
|
||||
|
||||
/* Scrive il valore trovato */
|
||||
*lpBuf ++ = (signed short)valpred[bufferstep];
|
||||
|
||||
bufferstep = !bufferstep;
|
||||
}
|
||||
|
||||
return eof / 2;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************\
|
||||
* Metodi per FPSOUND
|
||||
\****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user