private void ModsThreadMain(Object Args) { byte[] data = File.ReadAllBytes((String)Args); ModsDemuxer dm = new ModsDemuxer(new MemoryStream(data)); if ((dm.Header.AudioCodec == 1 || dm.Header.AudioCodec == 2 || dm.Header.AudioCodec == 3) && dm.Header.NbChannel > 0 && dm.Header.Frequency > 0) { AudioBuffer = new BufferedWaveProvider(new WaveFormat((int)dm.Header.Frequency, 16, dm.Header.NbChannel)); AudioBuffer.DiscardOnBufferOverflow = true; AudioBuffer.BufferLength = 1024 * 512; Player = new WaveOut(); Player.DesiredLatency = 150; Player.Init(AudioBuffer); Player.Play(); } Invoke((Action) delegate { ClientSize = new Size((int)dm.Header.Width, (int)dm.Header.Height); }); LibMobiclip.Codec.Mobiclip.MobiclipDecoder d = new LibMobiclip.Codec.Mobiclip.MobiclipDecoder(dm.Header.Width, dm.Header.Height, LibMobiclip.Codec.Mobiclip.MobiclipDecoder.MobiclipVersion.ModsDS); TimeSpan ts = TimeSpan.FromMilliseconds(1000d / (double)(dm.Header.Fps / (double)0x01000000)); int CurChannel = 0; List <short>[] channels = new List <short> [dm.Header.NbChannel]; IMAADPCMDecoder[] decoders = new IMAADPCMDecoder[dm.Header.NbChannel]; SxDecoder[] sxd = new SxDecoder[dm.Header.NbChannel]; FastAudioDecoder[] fad = new FastAudioDecoder[dm.Header.NbChannel]; bool[] isinit = new bool[dm.Header.NbChannel]; for (int i = 0; i < dm.Header.NbChannel; i++) { channels[i] = new List <short>(); decoders[i] = new IMAADPCMDecoder(); sxd[i] = new SxDecoder(); fad[i] = new FastAudioDecoder(); isinit[i] = false; } while (!StopThread) { uint NrAudioPackets; bool IsKeyFrame; byte[] framedata = dm.ReadFrame(out NrAudioPackets, out IsKeyFrame); if (framedata == null) { break; } d.Data = framedata; d.Offset = 0; Bitmap b = d.DecodeFrame(); if (NrAudioPackets > 0 && AudioBuffer != null) { int Offset = d.Offset - 2; if (dm.Header.TagId == 0x334E && (IOUtil.ReadU16LE(framedata, 0) & 0x8000) != 0) { Offset += 4; } if (dm.Header.AudioCodec == 3) { if (IsKeyFrame) { for (int i = 0; i < dm.Header.NbChannel; i++) { channels[i] = new List <short>(); decoders[i] = new IMAADPCMDecoder(); sxd[i] = new SxDecoder(); isinit[i] = false; } } for (int i = 0; i < NrAudioPackets; i++) { channels[CurChannel].AddRange(decoders[CurChannel].GetWaveData(framedata, Offset, 128 + (!isinit[CurChannel] ? 4 : 0))); Offset += 128 + (!isinit[CurChannel] ? 4 : 0); isinit[CurChannel] = true; CurChannel++; if (CurChannel >= dm.Header.NbChannel) { CurChannel = 0; } } } else if (dm.Header.AudioCodec == 1) { for (int i = 0; i < NrAudioPackets; i++) { if (!isinit[CurChannel]) { sxd[CurChannel].Codebook = dm.AudioCodebooks[CurChannel]; } isinit[CurChannel] = true; sxd[CurChannel].Data = framedata; sxd[CurChannel].Offset = Offset; channels[CurChannel].AddRange(sxd[CurChannel].Decode()); Offset = sxd[CurChannel].Offset; CurChannel++; if (CurChannel >= dm.Header.NbChannel) { CurChannel = 0; } } } else if (dm.Header.AudioCodec == 2) { for (int i = 0; i < NrAudioPackets; i++) { fad[CurChannel].Data = framedata; fad[CurChannel].Offset = Offset; channels[CurChannel].AddRange(fad[CurChannel].Decode()); Offset = fad[CurChannel].Offset; CurChannel++; if (CurChannel >= dm.Header.NbChannel) { CurChannel = 0; } } } int smallest = int.MaxValue; for (int i = 0; i < dm.Header.NbChannel; i++) { if (channels[i].Count < smallest) { smallest = channels[i].Count; } } if (smallest > 0) { //Gather samples short[][] samps = new short[dm.Header.NbChannel][]; for (int i = 0; i < dm.Header.NbChannel; i++) { samps[i] = new short[smallest]; channels[i].CopyTo(0, samps[i], 0, smallest); channels[i].RemoveRange(0, smallest); } byte[] result = InterleaveChannels(samps); AudioBuffer.AddSamples(result, 0, result.Length); } } if (lastval != 0) { while ((s.Value - lastval) < (long)(ts.TotalSeconds * s.Frequency)) { ; } } lastval = s.Value; try { pictureBox1.BeginInvoke((Action) delegate { pictureBox1.Image = b; pictureBox1.Invalidate(); }); } catch { } } }