static void Main(string[] args) { Console.WriteLine("ToyTools MP3 Decoder Demo"); if(args.Length != 3) { Console.WriteLine("Usage: ToyMP3Demo.exe <MP3 Filename> <OUTPUT FILENAME> <ch>"); return; } var mp3 = new ToyTools.ToyMP3(args[0]); var output = args[1]; var frame = new ToyTools.ToyMP3Frame(); var decoder = new ToyTools.ToyMP3Decoder(); var wout = new ToyWaveOut(); // main loop var sw = new Stopwatch(); var debug_framenum = 0; var loop = 0; wout.PublishWaveFile(output, int.Parse(args[2])); sw.Start(); try{ while(mp3.SeekMP3Frame(frame)) { decoder.DecodeFrame(frame); debug_framenum++; wout.AddData(decoder.Pcm); loop++; } } catch(Exception) { //Console.WriteLine(e); } sw.Stop(); var ts = sw.Elapsed; wout.FinishWriting(); Console.WriteLine( "spent time:{0} total frame:{1} clpped_samples:{2}", ts, debug_framenum, decoder.Clip); }
public async void loadHash(string path) { center.Visibility = System.Windows.Visibility.Collapsed; await Task.Delay(1); var mp3 = new ToyMP3(path); var frame = new ToyTools.ToyMP3Frame(); var decoder = new ToyTools.ToyMP3Decoder(); var list = new List<short>(); loading.Content = "Parseing..."; await Task.Delay(1); try { while (mp3.SeekMP3Frame(frame)) { decoder.DecodeFrame(frame); list.AddRange(decoder.Pcm); } } catch (Exception) { } wave = PickFloat(list.ToArray()).ToArray(); var bmp = new Bitmap((int)Math.Ceiling((double)wave.Length / 100), 100); loading.Content = "Drawing..."; await Task.Delay(1); AudioVisualizationService.DrawWave(wave, bmp); image.Source = bmp.ToBitmapSource(); loading.Visibility = System.Windows.Visibility.Collapsed; center.Visibility = System.Windows.Visibility.Visible; return; }
public bool DecodeFrame(ToyMP3Frame f) { frame = f; int PcmPoint = 0; // Adding data to the buffer bs.AddByteArray(frame.MainData); // Checking the buffer size and removing used data. if(bs.Length > buffer_size) { bs.RemoveRange( 0, bs.Length/8 - (frame.MainData.Length + frame.MainDataBegin) ); } // Checking if position of the buffer to read exists. if(frame.MainDataBegin > (bs.Length/8 - frame.MainDataSize)) { return false; } // Set reading location bs.Position = bs.Length-(frame.MainData.Length*8 + frame.MainDataBegin*8); // 1つのフレームは2個のグラニュールセットを持つ。 for(int gr=0; gr<2; gr++) { // Insie of granule-set, there exists glanule*frame.Channels for(int ch=0; ch<frame.Channels; ch++) { // End position of "Part2~3" (Scalefactor + Huffmancode) int p23_end_pos = bs.Position+frame.granule[ch, gr].Part23Length; DecodeScalefactor(frame.granule[ch,gr], ch, gr); if(!DecodeHuffmanCode(ch, gr, p23_end_pos)) { return false; } bs.Position = p23_end_pos; } // Generate sample map for(int ch=0; ch<frame.Channels; ch++) { CreateSampleMap(ch,gr); } // Dequantize(and reorder) for(int ch=0; ch<frame.Channels; ch++) { Dequantize(ch,gr); } // Joint Stereo decode JointStereoDecode(); // AntiAlias for(int ch=0; ch<frame.Channels; ch++) { Antialias(ch,gr); } // InverseMDCTSynthesys for(int ch=0; ch<frame.Channels; ch++) { InverseMDCTSynthesys(ch, gr); } // SubbandSynthesys for(int ch=0; ch<frame.Channels; ch++) { SubbandSynthesys(ch); } // Generate PCM CreatePcm(gr); PcmPoint += 576 * frame.Channels; } //PcmDataNum = PcmPoint; return true; }
private bool DecodeSideTableInformation(ToyMP3Frame frame) { frame.MainDataBegin = bs.GetByInt(9); // Skipping Private Bits if(frame.Channels == 1) { bs.Skip(5); } else { bs.Skip(3); } // Get Scfsi for(int ch = 0; ch < frame.Channels; ch++) { for(int i = 0; i < 4; i++) { frame.SetScfsi(ch, i, bs.GetByInt(1)); } } // Get Granule Info for(int g = 0; g < 2; g++) { for(int ch = 0; ch < frame.Channels; ch++) { frame.granule[ch, g].Part23Length = bs.GetByInt(12); frame.granule[ch, g].BigValues = bs.GetByInt(9); frame.granule[ch, g].GlobalGain = bs.GetByInt(8); frame.granule[ch, g].ScalefacCompress = bs.GetByInt(4); frame.granule[ch, g].WindowSwitchingFlag = bs.GetByInt(1); if(frame.granule[ch, g].WindowSwitchingFlag == 1) { frame.granule[ch, g].BlockType = bs.GetByInt(2); frame.granule[ch, g].MixedBlockFlag = bs.GetByInt(1); if(frame.granule[ch, g].BlockType == 0) { return false; } for(int w = 0; w < 2; w++) { frame.granule[ch, g].SetTableSelect(w, bs.GetByInt(5)); } for(int w = 0; w < 3; w++) { frame.granule[ch, g].SetSubblockGain(w, bs.GetByInt(3)); } if( (frame.granule[ch, g].BlockType == 2) && (frame.granule[ch, g].MixedBlockFlag == 0)) { frame.granule[ch, g].Region0Count= 8; frame.granule[ch, g].Region1Count= 36; } else { frame.granule[ch, g].Region0Count = 7; frame.granule[ch, g].Region1Count = 36; } } else { for(int w = 0; w < 3; w++) { frame.granule[ch, g].SetTableSelect(w, bs.GetByInt(5)); } frame.granule[ch, g].Region0Count = bs.GetByInt(4); frame.granule[ch, g].Region1Count = bs.GetByInt(3); frame.granule[ch, g].MixedBlockFlag = 0; frame.granule[ch, g].BlockType = 0; } frame.granule[ch, g].PreFlag = bs.GetByInt(1); frame.granule[ch, g].ScalefacScale = bs.GetByInt(1); frame.granule[ch, g].Count1TableSelect = bs.GetByInt(1); } } return true; }
// Seek Mpeg Frame Header and gether information public bool SeekMP3Frame(ToyMP3Frame frame) { for(;;) { for(int i=0; ; i++) { var syncword = bs.GetByInt(12); // search syncword if(bs.GetByInt(12) != 4095) { if(i > frame_seek_limit) { return false; } // back 1 byte (in order to check byte by byte) bs.Skip(-4); continue; } else { break; } } // Data must be casted into correct type. frame.Id = bs.GetByInt(1); frame.Layer = bs.GetByInt(2); frame.ProtectionBit = bs.GetByInt(1); frame.BitrateIndex = bs.GetByInt(4); frame.FrequencyIndex = bs.GetByInt(2); frame.PaddingBit = bs.GetByInt(1); frame.PrivateBit = bs.GetByInt(1); frame.Mode = bs.GetByInt(2); frame.ModeExtention = bs.GetByInt(2); frame.Copyright = bs.GetByInt(1); frame.Original = bs.GetByInt(1); frame.Emphasis = bs.GetByInt(2); if(frame.IsValidHeader) { // escaping from this loop break; } else { // Step back 3 bytes, and continue seeking. bs.Skip(-24); } } // CRC word if(frame.ProtectionBit == 0) { frame.CRCCheck = bs.GetByInt(16); } else { frame.CRCCheck = 0; } if(!DecodeSideTableInformation(frame)) { return false; } // Format check if(frame.Id != 1 || frame.Layer != 1 || frame.BitrateIndex == 0) { return false; } // MainData if(frame.MainDataSize < 0) { return false; } frame.MainData = bs.GetByByteArray(frame.MainDataSize); return true; }