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