mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 17:43:08 -05:00
fix vorbis decoding issues when multiple instances are run on different threads
This commit is contained in:
parent
1e6bcd5306
commit
a95d0ba3b1
8 changed files with 45 additions and 56 deletions
|
@ -69,7 +69,6 @@ namespace ClassicalSharp.Audio {
|
|||
}
|
||||
}
|
||||
|
||||
IAudioOutput firstSoundOut;
|
||||
void PlayCurrentSound(IAudioOutput[] outputs, float volume) {
|
||||
for (int i = 0; i < monoOutputs.Length; i++) {
|
||||
IAudioOutput output = outputs[i];
|
||||
|
@ -116,10 +115,6 @@ namespace ClassicalSharp.Audio {
|
|||
void DisposeSound() {
|
||||
DisposeOutputs(ref monoOutputs);
|
||||
DisposeOutputs(ref stereoOutputs);
|
||||
if (firstSoundOut != null) {
|
||||
firstSoundOut.Dispose();
|
||||
firstSoundOut = null;
|
||||
}
|
||||
}
|
||||
|
||||
void DisposeOutputs(ref IAudioOutput[] outputs) {
|
||||
|
|
|
@ -83,8 +83,8 @@ namespace csvorbis
|
|||
}
|
||||
|
||||
// unpack_header enforces range checking
|
||||
int type = vi.map_type[vi.mode_param[mode].mapping];
|
||||
return(FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
|
||||
FuncMapping mapping = vi.map_funcs[vi.mode_param[mode].mapping];
|
||||
return mapping.inverse(this, vd.mode[mode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace csvorbis
|
|||
// given a list of word lengths, generate a list of codewords. Works
|
||||
// for length ordered or unordered, always assigns the lowest valued
|
||||
// codewords first. Extended to handle unused entries (length 0)
|
||||
internal static int[] make_words(int[] l, int n)
|
||||
internal int[] make_words(int[] l, int n)
|
||||
{
|
||||
int[] marker = new int[33];
|
||||
int[] r = new int[n];
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace csvorbis
|
|||
{
|
||||
public class DspState
|
||||
{
|
||||
static float M_PI = 3.1415926539f;
|
||||
const float M_PI = 3.1415926539f;
|
||||
|
||||
internal Info vi;
|
||||
internal int modebits;
|
||||
|
@ -78,7 +78,7 @@ namespace csvorbis
|
|||
wnd[1][1][1] = new float[2];
|
||||
}
|
||||
|
||||
internal static float[] window(int wnd, int left, int right)
|
||||
internal float[] window(int wnd, int left, int right)
|
||||
{
|
||||
float[] ret = new float[wnd];
|
||||
// The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
|
||||
|
@ -158,10 +158,9 @@ namespace csvorbis
|
|||
|
||||
for(int i = 0;i<vi.modes;i++) {
|
||||
int mapnum = vi.mode_param[i].mapping;
|
||||
int maptype = vi.map_type[mapnum];
|
||||
FuncMapping mapping = vi.map_funcs[mapnum];
|
||||
|
||||
mode[i] = FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i],
|
||||
vi.map_param[mapnum]);
|
||||
mode[i] = mapping.look(this,vi.mode_param[i], vi.map_param[mapnum]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,6 @@ namespace csvorbis
|
|||
{
|
||||
abstract class FuncFloor
|
||||
{
|
||||
public static FuncFloor[] floor_P = {null,new Floor1()};
|
||||
|
||||
public abstract Object unpack(Info vi, csBuffer opb);
|
||||
public abstract Object look(DspState vd, InfoMode mi, Object i);
|
||||
public abstract Object inverse1(Block vb, Object i, Object memo);
|
||||
|
@ -40,7 +38,7 @@ namespace csvorbis
|
|||
|
||||
class Floor1 : FuncFloor
|
||||
{
|
||||
static int VIF_POSIT = 63;
|
||||
const int VIF_POSIT = 63;
|
||||
|
||||
public override Object unpack(Info vi , csBuffer opb)
|
||||
{
|
||||
|
@ -352,7 +350,7 @@ namespace csvorbis
|
|||
return(null);
|
||||
}
|
||||
|
||||
private static int render_point(int x0,int x1,int y0,int y1,int x)
|
||||
private int render_point(int x0,int x1,int y0,int y1,int x)
|
||||
{
|
||||
y0 &= 0x7fff; /* mask off flag */
|
||||
y1 &= 0x7fff;
|
||||
|
@ -467,7 +465,7 @@ namespace csvorbis
|
|||
0.82788260F, 0.88168307F, 0.9389798F, 1.0F
|
||||
};
|
||||
|
||||
private static void render_line(int x0, int x1,int y0,int y1,float[] d)
|
||||
private void render_line(int x0, int x1,int y0,int y1,float[] d)
|
||||
{
|
||||
int dy = y1-y0;
|
||||
int adx = x1-x0;
|
||||
|
@ -535,7 +533,7 @@ namespace csvorbis
|
|||
|
||||
class LookFloor1
|
||||
{
|
||||
static int VIF_POSIT = 63;
|
||||
const int VIF_POSIT = 63;
|
||||
|
||||
internal int[] sorted_index = new int[VIF_POSIT+2];
|
||||
internal int[] forward_index = new int[VIF_POSIT+2];
|
||||
|
|
|
@ -30,8 +30,6 @@ namespace csvorbis
|
|||
{
|
||||
abstract class FuncMapping
|
||||
{
|
||||
public static FuncMapping[] mapping_P = {new Mapping0()};
|
||||
|
||||
public abstract Object unpack(Info info , csBuffer buffer);
|
||||
public abstract Object look(DspState vd, InfoMode vm, Object m);
|
||||
public abstract int inverse(Block vd, Object lm);
|
||||
|
@ -58,11 +56,11 @@ namespace csvorbis
|
|||
int floornum = info.floorsubmap[i];
|
||||
int resnum = info.residuesubmap[i];
|
||||
|
||||
looks.floor_func[i] = FuncFloor.floor_P[vi.floor_type[floornum]];
|
||||
looks.floor_func[i] = vi.floor_funcs[floornum];
|
||||
looks.floor_look[i] = looks.floor_func[i].
|
||||
look(vd,vm,vi.floor_param[floornum]);
|
||||
|
||||
looks.residue_func[i] = FuncResidue.residue_P[vi.residue_type[resnum]];
|
||||
looks.residue_func[i] = vi.residue_funcs[resnum];
|
||||
looks.residue_look[i] = looks.residue_func[i].
|
||||
look(vd,vm,vi.residue_param[resnum]);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,11 @@ namespace csvorbis
|
|||
{
|
||||
abstract class FuncResidue
|
||||
{
|
||||
public static FuncResidue[] residue_P = {new Residue0(), new Residue1(), new Residue2()};
|
||||
|
||||
public static FuncResidue make(int type) {
|
||||
if (type == 0) return new Residue0();
|
||||
if (type == 1) return new Residue1();
|
||||
return new Residue2();
|
||||
}
|
||||
public abstract Object unpack(Info vi, csBuffer opb);
|
||||
public abstract Object look(DspState vd, InfoMode vm, Object vr);
|
||||
|
||||
|
@ -119,9 +122,9 @@ namespace csvorbis
|
|||
return(look);
|
||||
}
|
||||
|
||||
static int[][][] partword = new int[2][][];
|
||||
int[][][] partword = new int[2][][];
|
||||
|
||||
internal static int _01inverse(Block vb, Object vl, float[][] fin, int ch, int decodepart)
|
||||
internal int _01inverse(Block vb, Object vl, float[][] fin, int ch, int decodepart)
|
||||
{
|
||||
int i,j,k,l,s;
|
||||
LookResidue0 look = (LookResidue0 )vl;
|
||||
|
@ -190,7 +193,7 @@ namespace csvorbis
|
|||
return(0);
|
||||
}
|
||||
|
||||
internal static int _2inverse(Block vb, Object vl, float[][] fin, int ch)
|
||||
internal int _2inverse(Block vb, Object vl, float[][] fin, int ch)
|
||||
{
|
||||
int i,k,l,s;
|
||||
LookResidue0 look = (LookResidue0 )vl;
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace csvorbis
|
|||
|
||||
public class Info
|
||||
{
|
||||
private static int OV_ENOTAUDIO = -135;
|
||||
private const int OV_ENOTAUDIO = -135;
|
||||
|
||||
public int version, channels, rate;
|
||||
|
||||
|
@ -55,13 +55,13 @@ namespace csvorbis
|
|||
|
||||
internal InfoMode[] mode_param = null;
|
||||
|
||||
internal int[] map_type = null;
|
||||
internal FuncMapping[] map_funcs = null;
|
||||
internal Object[] map_param = null;
|
||||
|
||||
internal int[] floor_type = null;
|
||||
internal Floor1[] floor_funcs = null;
|
||||
internal Object[] floor_param = null;
|
||||
|
||||
internal int[] residue_type = null;
|
||||
internal FuncResidue[] residue_funcs = null;
|
||||
internal Object[] residue_param = null;
|
||||
|
||||
internal StaticCodeBook[] book_param = null;
|
||||
|
@ -96,7 +96,7 @@ namespace csvorbis
|
|||
|
||||
void unpack_books(csBuffer opb) {
|
||||
books = opb.read(8) + 1;
|
||||
CheckEntries(ref book_param, books);
|
||||
book_param = new StaticCodeBook[books];
|
||||
for(int i = 0;i < books;i++) {
|
||||
book_param[i] = new StaticCodeBook();
|
||||
book_param[i].unpack(opb);
|
||||
|
@ -107,28 +107,37 @@ namespace csvorbis
|
|||
opb.read(16);
|
||||
|
||||
floors = opb.read(6) + 1;
|
||||
CheckEntries(ref floor_param, ref floor_type, floors);
|
||||
floor_funcs = new Floor1[floors];
|
||||
floor_param = new object[floors];
|
||||
for(int i = 0;i<floors;i++) {
|
||||
floor_type[i] = opb.read(16);
|
||||
floor_param[i] = FuncFloor.floor_P[floor_type[i]].unpack(this,opb);
|
||||
int type = opb.read(16);
|
||||
if (type != 1) throw new csorbisException("floor type must be 1");
|
||||
floor_funcs[i] = new Floor1();
|
||||
floor_param[i] = floor_funcs[i].unpack(this,opb);
|
||||
}
|
||||
|
||||
residues = opb.read(6) + 1;
|
||||
CheckEntries(ref residue_param, ref residue_type, residues);
|
||||
residue_funcs = new FuncResidue[residues];
|
||||
residue_param = new object[residues];
|
||||
for(int i = 0;i<residues;i++) {
|
||||
residue_type[i] = opb.read(16);
|
||||
residue_param[i] = FuncResidue.residue_P[residue_type[i]].unpack(this,opb);
|
||||
int type = opb.read(16);
|
||||
if (type > 2) throw new csorbisException("residue type must be <= 2");
|
||||
residue_funcs[i] = FuncResidue.make(type);
|
||||
residue_param[i] = residue_funcs[i].unpack(this,opb);
|
||||
}
|
||||
|
||||
maps = opb.read(6) + 1;
|
||||
CheckEntries(ref map_param, ref map_type, maps);
|
||||
map_funcs = new FuncMapping[maps];
|
||||
map_param = new object[maps];
|
||||
for(int i = 0;i<maps;i++) {
|
||||
map_type[i] = opb.read(16);
|
||||
map_param[i] = FuncMapping.mapping_P[map_type[i]].unpack(this,opb);
|
||||
int type = opb.read(16);
|
||||
if (type != 0) throw new csorbisException("mapping type must be 0");
|
||||
map_funcs[i] = new Mapping0();
|
||||
map_param[i] = map_funcs[i].unpack(this,opb);
|
||||
}
|
||||
|
||||
modes = opb.read(6) + 1;
|
||||
CheckEntries(ref mode_param, modes);
|
||||
mode_param = new InfoMode[modes];
|
||||
for(int i = 0;i<modes;i++) {
|
||||
mode_param[i] = new InfoMode();
|
||||
mode_param[i].blockflag = opb.read(1);
|
||||
|
@ -138,19 +147,6 @@ namespace csvorbis
|
|||
}
|
||||
opb.read(1);
|
||||
}
|
||||
|
||||
void CheckEntries<T>(ref T[] array, int count) {
|
||||
if(array == null || array.Length != count) {
|
||||
array = new T[count];
|
||||
}
|
||||
}
|
||||
|
||||
void CheckEntries<T>(ref T[] array, ref int[] types, int count) {
|
||||
if(array == null || array.Length != count) {
|
||||
array = new T[count];
|
||||
types = new int[count];
|
||||
}
|
||||
}
|
||||
|
||||
public void synthesis_headerin(Comment vc, Packet op) {
|
||||
if(op == null) return;
|
||||
|
|
Loading…
Add table
Reference in a new issue