prepare BRR encoding/decoding
This commit is contained in:
parent
b7e618e91d
commit
8eaddcf070
|
@ -444,6 +444,7 @@ src/engine/platform/ym2608Interface.cpp
|
|||
src/engine/platform/ym2610Interface.cpp
|
||||
|
||||
src/engine/blip_buf.c
|
||||
src/engine/brrUtils.c
|
||||
src/engine/safeReader.cpp
|
||||
src/engine/safeWriter.cpp
|
||||
src/engine/config.cpp
|
||||
|
|
82
src/engine/brrUtils.c
Normal file
82
src/engine/brrUtils.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* brrUtils - BRR audio codec utilities
|
||||
* Copyright (C) 2022 tildearrow
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "brrUtils.h"
|
||||
|
||||
void brrEncode(short* buf, unsigned char* out, long len) {
|
||||
if (len==0) return;
|
||||
// TODO
|
||||
}
|
||||
|
||||
#define DO_ONE_SAMPLE \
|
||||
if (next&8) next|=0xfff8; \
|
||||
\
|
||||
next<<=(buf[0]>>4); /* range */ \
|
||||
\
|
||||
switch (control&0xc) { /* filter */ \
|
||||
case 0: \
|
||||
break; \
|
||||
case 4: \
|
||||
next+=(last1*15)/16; \
|
||||
break; \
|
||||
case 8: \
|
||||
next+=(last1*61)/32-(last2*15)/16; \
|
||||
break; \
|
||||
case 12: \
|
||||
next+=(last1*115)/64-(last2*13)/16; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (next>32767) next=32767; \
|
||||
if (next<-32768) next=-32768; \
|
||||
\
|
||||
last2=last1; \
|
||||
last1=next; \
|
||||
*out=next; \
|
||||
out++;
|
||||
|
||||
void brrDecode(unsigned char* buf, short* out, long len) {
|
||||
if (len==0) return;
|
||||
|
||||
int last1=0;
|
||||
int last2=0;
|
||||
int next=0;
|
||||
|
||||
// don't read out of bounds
|
||||
len-=8;
|
||||
|
||||
for (long i=0; i<len; i+=9) {
|
||||
unsigned char control=buf[0];
|
||||
|
||||
for (unsigned char j=1; j<9; j++) {
|
||||
next=buf[j]&15;
|
||||
DO_ONE_SAMPLE;
|
||||
|
||||
next=buf[j]>>4;
|
||||
DO_ONE_SAMPLE;
|
||||
}
|
||||
|
||||
// end bit
|
||||
if (control&1) break;
|
||||
buf+=9;
|
||||
}
|
||||
}
|
50
src/engine/brrUtils.h
Normal file
50
src/engine/brrUtils.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* brrUtils - BRR audio codec utilities
|
||||
* Copyright (C) 2022 tildearrow
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BRR_UTILS_H
|
||||
#define _BRR_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* read len samples from buf, encode in BRR and output to out.
|
||||
* @param buf input data.
|
||||
* @param out output buffer. shall be at least 9*(len/16) shorts in size.
|
||||
* @param len input length (should be a multiple of 16. if it isn't, the output will be padded).
|
||||
*/
|
||||
void brrEncode(short* buf, unsigned char* out, long len);
|
||||
|
||||
/**
|
||||
* read len bytes from buf, decode BRR and output to out.
|
||||
* @param buf input data.
|
||||
* @param out output buffer. shall be at least 16*(len/9) shorts in size.
|
||||
* @param len input length (shall be a multiple of 9).
|
||||
*/
|
||||
void brrDecode(unsigned char* buf, short* out, long len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#define CHIP_FREQBASE 131072
|
||||
|
||||
#define rWrite(a,v) {dsp.write(a,v); regPool[(a)&0x7f]=v; }
|
||||
#define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} }
|
||||
#define chWrite(c,a,v) {rWrite((a)+(c)*16,v)}
|
||||
#define sampleTableAddr(c) (sampleTableBase+(c)*4)
|
||||
#define waveTableAddr(c) (sampleTableBase+8*4+(c)*9*16)
|
||||
|
@ -69,6 +69,14 @@ void DivPlatformSNES::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
short out[2];
|
||||
short chOut[16];
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
// TODO: delay
|
||||
if (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
dsp.write(w.addr,w.val);
|
||||
regPool[w.addr&0x7f]=w.val;
|
||||
writes.pop();
|
||||
}
|
||||
|
||||
dsp.set_output(out,1);
|
||||
dsp.run(32);
|
||||
dsp.get_voice_outputs(chOut);
|
||||
|
@ -407,7 +415,9 @@ void DivPlatformSNES::reset() {
|
|||
dsp.set_output(NULL,0);
|
||||
memset(regPool,0,128);
|
||||
// TODO more initial values
|
||||
sampleTableBase=0x100; // hack: this can't be 0 or channel 1 won't play??
|
||||
// this can't be 0 or channel 1 won't play
|
||||
// this can't be 0x100 either as that's used by SPC700 page 1 and the stack
|
||||
sampleTableBase=0x200;
|
||||
rWrite(0x5d,sampleTableBase>>8);
|
||||
rWrite(0x0c,127); // global volume left
|
||||
rWrite(0x1c,127); // global volume right
|
||||
|
|
|
@ -73,6 +73,13 @@ class DivPlatformSNES: public DivDispatch {
|
|||
signed char gblVolL, gblVolR;
|
||||
size_t sampleTableBase;
|
||||
|
||||
struct QueuedWrite {
|
||||
unsigned char addr;
|
||||
unsigned char val;
|
||||
QueuedWrite(unsigned char a, unsigned char v): addr(a), val(v) {}
|
||||
};
|
||||
std::queue<QueuedWrite> writes;
|
||||
|
||||
signed char sampleMem[65536];
|
||||
size_t sampleMemLen;
|
||||
unsigned char regPool[0x80];
|
||||
|
|
|
@ -33,6 +33,7 @@ extern "C" {
|
|||
#include "../../extern/adpcm/ymb_codec.h"
|
||||
#include "../../extern/adpcm/ymz_codec.h"
|
||||
}
|
||||
#include "brrUtils.h"
|
||||
|
||||
DivSampleHistory::~DivSampleHistory() {
|
||||
if (data!=NULL) delete[] data;
|
||||
|
@ -851,7 +852,7 @@ void DivSample::render() {
|
|||
}
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_BRR: // BRR
|
||||
// TODO!
|
||||
brrDecode(dataBRR,data16,samples);
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
||||
oki_decode(dataVOX,data16,samples);
|
||||
|
@ -908,7 +909,10 @@ void DivSample::render() {
|
|||
data8[i]=data16[i]>>8;
|
||||
}
|
||||
}
|
||||
// TODO: BRR!
|
||||
if (depth!=DIV_SAMPLE_DEPTH_VOX) { // BRR
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_BRR,samples)) return;
|
||||
brrEncode(data16,dataBRR,samples);
|
||||
}
|
||||
if (depth!=DIV_SAMPLE_DEPTH_VOX) { // VOX
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;
|
||||
oki_encode(data16,dataVOX,samples);
|
||||
|
|
Loading…
Reference in a new issue