예제 #1
0
        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 { }
            }
        }