private void FMV_Load(object sender, EventArgs e) { /*double ticks = 10000000.0 / (Video.Header.FrameRate / 256.0); * float exp = (float)(ticks - Math.Floor(ticks)); * if (exp != 0) * { * int i = 0; * float result; * do * { * i++; * result = exp * i; * } * while((float)(result - Math.Floor(result)) != 0); * }*/ //TODO: Calculate timing based on fps if ((Video.Header.Flags & 4) == 4) { AudioConverter = new IMAADPCMDecoder(); AudioBuffer = new NAudio.Wave.BufferedWaveProvider(new NAudio.Wave.WaveFormat((int)Video.Header.AudioRate, 16, 1)); AudioBuffer.DiscardOnBufferOverflow = true; AudioBuffer.BufferLength = 8192 * 16; Player = new NAudio.Wave.WaveOut(); Player.DesiredLatency = 150; Player.Init(AudioBuffer); Player.Play(); } new System.Threading.Thread(new System.Threading.ThreadStart(delegate { int state = 0; while (!stop) { if (Frames.Count != 0) { pictureBox1.Image = Frames.Dequeue(); switch (state) { case 0: System.Threading.Thread.Sleep(TimeSpan.FromTicks(666666)); break; case 1: System.Threading.Thread.Sleep(TimeSpan.FromTicks(666667)); break; case 2: System.Threading.Thread.Sleep(TimeSpan.FromTicks(666667)); break; } state = (state + 1) % 3; } } System.Threading.Thread.CurrentThread.Abort(); })).Start(); backgroundWorker1.RunWorkerAsync(); }
/// <summary> /// Convert file to RIFF. /// </summary> /// <returns></returns> public RIFF toRIFF() { RIFF r = new RIFF(); r.fmt.bitsPerSample = 8; r.fmt.chunkFormat = 1; r.fmt.numChannels = head.numChannel; r.fmt.restOfData = new byte[0]; r.fmt.sampleRate = head.nSampleRate; switch (head.waveType) { case 0: r.data.pcm8 = new byte[r.fmt.numChannels][]; for (int i = 0; i < data.pcm8.Length; i++) { r.data.pcm8[i] = new byte[data.pcm8[i].Length]; for (int j = 0; j < data.pcm8[i].Length; j++) { r.data.pcm8[i][j] = (byte)(data.pcm8[i][j] + 0x80); } } r.unpackPCMChannels(); break; case 1: r.fmt.bitsPerSample = 16; r.data.pcm16 = new short[r.fmt.numChannels][]; for (int i = 0; i < data.pcm16.Length; i++) { r.data.pcm16[i] = new short[data.pcm16[i].Length]; for (int j = 0; j < data.pcm16[i].Length; j++) { r.data.pcm16[i][j] = data.pcm16[i][j]; } } r.unpackPCMChannels(); break; case 2: r.fmt.bitsPerSample = 16; r.data.pcm16 = new short[r.fmt.numChannels][]; //Convert IMA-ADPCM to PCM16. short[][] newSamples = new short[r.fmt.numChannels][]; for (int i = 0; i < r.fmt.numChannels; i++) { List <short> samples = new List <short>(); int blockCount = 0; foreach (dataBlock.imaAdpcmBlock a in data.imaAdpcm[i]) { IMAADPCMDecoder d = new IMAADPCMDecoder(a.data, 0); int sampleCount = 0; if (blockCount != head.nBlock - 1) { foreach (byte b in a.data) { if (sampleCount < head.nBlockSample) { try { samples.Add(d.GetSample()); } catch { } } sampleCount += 1; if (sampleCount < head.nBlockSample) { try { samples.Add(d.GetSample()); } catch { } } sampleCount += 1; } } else { foreach (byte b in a.data) { if (sampleCount < head.nLastBlockSample) { try { samples.Add(d.GetSample()); } catch { } } sampleCount += 1; if (sampleCount < head.nLastBlockSample) { try { samples.Add(d.GetSample()); } catch { } } sampleCount += 1; } } blockCount += 1; } newSamples[i] = samples.ToArray(); } r.data.pcm16 = newSamples; r.unpackPCMChannels(); break; } //Make loop. if (head.loop == 1) { r.smpl = new RIFF.smplBlock(); r.smpl.loopStart = head.nLoopOffset; r.smpl.loopEnd = head.nSample; } r.update(); return(r); }
/// <summary> /// Convert to RIFF. /// </summary> /// <returns></returns> public RIFF toRIFF() { RIFF r = new RIFF(); r.data = new RIFF.dataBlock(); r.fmt = new RIFF.fmtBlock(); r.fmt.bitsPerSample = 8; r.fmt.sampleRate = (UInt32)data.info.nSampleRate; r.fmt.restOfData = new byte[0]; r.fmt.chunkFormat = 1; r.fmt.numChannels = 1; switch (data.info.waveType) { case 0: r.data.data = new byte[data.pcm8.Length]; for (int i = 0; i < r.data.data.Length; i++) { r.data.data[i] = (byte)((data.pcm8[i] + 0x80)); } break; case 1: r.fmt.bitsPerSample = 16; MemoryStream o = new MemoryStream(); BinaryWriter bw = new BinaryWriter(o); foreach (short s in data.pcm16) { bw.Write(s); } r.data.data = o.ToArray(); break; case 2: MemoryStream o2 = new MemoryStream(); BinaryWriter bw2 = new BinaryWriter(o2); r.fmt.bitsPerSample = 16; List <short> std = new List <short>(); IMAADPCMDecoder d = new IMAADPCMDecoder(data.imaAdpcm, 0); foreach (byte b in data.imaAdpcm) { try { std.Add(d.GetSample()); } catch { } try { std.Add(d.GetSample()); } catch { } } foreach (short s in std) { bw2.Write(s); } r.data.data = o2.ToArray(); break; } //Make looping RIFF. if (data.info.loopFlag == 1) { r.smpl = new RIFF.smplBlock(); switch (data.info.waveType) { case 0: r.smpl.loopStart = (UInt32)data.info.nloopOffset * 4; r.smpl.loopEnd = (UInt32)r.data.data.Length; break; case 1: r.smpl.loopStart = (UInt32)data.info.nloopOffset * 2; r.smpl.loopEnd = (UInt32)r.data.data.Length / 2; break; case 2: r.smpl.loopStart = (UInt32)data.info.nloopOffset * 8; r.smpl.loopEnd = (UInt32)r.data.data.Length / 2; break; } } r.update(); return(r); }
public static void Process(string srcfile, string outDir, out double fps) { MobiclipDecoder decoder = null; MemoryStream audio = null; FastAudioDecoder[] mFastAudioDecoders = null; int audiorate = -1; int audiochannels = 0; //VideoStream vs = null; FileStream stream = File.OpenRead(srcfile); var d = new MoLiveDemux(stream); int PlayingVideoStream = -1; int frameCount = 0; double finalFps = 0; d.OnCompleteFrameReceived += delegate(MoLiveChunk Chunk, byte[] Data) { if ((Chunk is MoLiveStreamVideo || Chunk is MoLiveStreamVideoWithLayout) && ((PlayingVideoStream == -1) || ((MoLiveStream)Chunk).StreamIndex == PlayingVideoStream)) { if (decoder == null) { decoder = new MobiclipDecoder(((MoLiveStreamVideo)Chunk).Width, ((MoLiveStreamVideo)Chunk).Height, MobiclipDecoder.MobiclipVersion.Moflex3DS); PlayingVideoStream = ((MoLiveStream)Chunk).StreamIndex; } decoder.Data = Data; decoder.Offset = 0; Bitmap b = decoder.DecodeFrame(); b.Save(outDir + "frame" + Util.NumToNo(frameCount, 8) + ".png", ImageFormat.Png); frameCount++; finalFps = (double)((MoLiveStreamVideo)Chunk).FpsRate / ((double)((MoLiveStreamVideo)Chunk).FpsScale); } else if (Chunk is MoLiveStreamAudio) { if (audio == null) { audio = new MemoryStream(); audiochannels = (int)((MoLiveStreamAudio)Chunk).Channel; audiorate = (int)((MoLiveStreamAudio)Chunk).Frequency; } switch ((int)((MoLiveStreamAudio)Chunk).CodecId) { case 0: //fastaudio { if (mFastAudioDecoders == null) { mFastAudioDecoders = new FastAudioDecoder[(int)((MoLiveStreamAudio)Chunk).Channel]; for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { mFastAudioDecoders[i] = new FastAudioDecoder(); } } List <short>[] channels = new List <short> [(int)((MoLiveStreamAudio)Chunk).Channel]; for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { channels[i] = new List <short>(); } int offset = 0; int size = 40; while (offset + size < Data.Length) { for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { mFastAudioDecoders[i].Data = Data; mFastAudioDecoders[i].Offset = offset; channels[i].AddRange(mFastAudioDecoders[i].Decode()); offset = mFastAudioDecoders[i].Offset; } } short[][] channelsresult = new short[(int)((MoLiveStreamAudio)Chunk).Channel][]; for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { channelsresult[i] = channels[i].ToArray(); } byte[] result = InterleaveChannels(channelsresult); audio.Write(result, 0, result.Length); } break; case 1: //IMA-ADPCM { IMAADPCMDecoder[] decoders = new IMAADPCMDecoder[(int)((MoLiveStreamAudio)Chunk).Channel]; List <short>[] channels = new List <short> [(int)((MoLiveStreamAudio)Chunk).Channel]; for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { decoders[i] = new IMAADPCMDecoder(); decoders[i].GetWaveData(Data, 4 * i, 4); channels[i] = new List <short>(); } int offset = 4 * (int)((MoLiveStreamAudio)Chunk).Channel; int size = 128 * (int)((MoLiveStreamAudio)Chunk).Channel; while (offset + size < Data.Length) { for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { channels[i].AddRange(decoders[i].GetWaveData(Data, offset, 128)); offset += 128; } } short[][] channelsresult = new short[(int)((MoLiveStreamAudio)Chunk).Channel][]; for (int i = 0; i < (int)((MoLiveStreamAudio)Chunk).Channel; i++) { channelsresult[i] = channels[i].ToArray(); } byte[] result = InterleaveChannels(channelsresult); audio.Write(result, 0, result.Length); } break; case 2: //PCM16 { audio.Write(Data, 0, Data.Length - (Data.Length % ((int)((MoLiveStreamAudio)Chunk).Channel * 2))); } break; } } }; int counter = 0; while (true) { uint error = d.ReadPacket(); if (error == 73) { break; } counter++; if (counter == 50) { counter = 0; } } if (audio != null) { //Write WAV byte[] adata = audio.ToArray(); audio.Close(); byte[] head = new byte[0x2C + adata.Length]; new byte[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F' }.CopyTo(head, 0x0); BitConverter.GetBytes((Int32)(0x2C - 8 + adata.Length)).CopyTo(head, 0x4); new byte[] { (byte)'W', (byte)'A', (byte)'V', (byte)'E' }.CopyTo(head, 0x8); new byte[] { (byte)'f', (byte)'m', (byte)'t', 0x20 }.CopyTo(head, 0xC); BitConverter.GetBytes((Int32)0x10).CopyTo(head, 0x10); BitConverter.GetBytes((Int16)0x1).CopyTo(head, 0x14); head[0x16] = (byte)audiochannels; BitConverter.GetBytes((Int32)audiorate).CopyTo(head, 0x18); BitConverter.GetBytes((Int32)(audiorate * audiochannels * 2)).CopyTo(head, 0x1C); BitConverter.GetBytes((Int16)(audiochannels * 2)).CopyTo(head, 0x20); head[0x22] = 16; new byte[] { (byte)'d', (byte)'a', (byte)'t', (byte)'a' }.CopyTo(head, 0x24); BitConverter.GetBytes((Int32)(adata.Length)).CopyTo(head, 0x28); adata.CopyTo(head, 0x2C); File.WriteAllBytes(outDir + "audio.wav", head); } stream.Close(); fps = finalFps; Console.WriteLine("FPS:" + finalFps); }