fix vorbis decoding issues when multiple instances are run on different threads

This commit is contained in:
UnknownShadow200 2018-08-06 02:32:32 +10:00
parent 1e6bcd5306
commit a95d0ba3b1
8 changed files with 45 additions and 56 deletions

View file

@ -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) {

View file

@ -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]);
}
}
}

View file

@ -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];

View file

@ -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]);
}
}

View file

@ -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];

View file

@ -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]);
}

View file

@ -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;

View file

@ -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;