public CassetteData[] ChunkData(SoundData data) { IEnumerator<Int16> ie = data.GetEnumerator(); float average = 0; int count = 0; ie.MoveNext(); List<CassetteData> chunks = new List<CassetteData>(); MetaData meta = null; do { Int16 level = ie.Current, abs = Math.Abs(level); int rate; // Eat a little first to even out the average, then start checking. if (count >= IgnoreHead) { if (level > 5 * average && (rate = FindLeader(ie)) > 0) { if (meta == null) { MetaParser parser = new MetaParser(ie, rate); meta = (MetaData) parser.Parse(); } else { ProgramParser parser = new ProgramParser(ie, rate, meta.ProgramSize); ProgramData program = (ProgramData) parser.Parse(); chunks.Add(new CassetteData(meta, program)); meta = null; } rate = count = 0; } } // Don't let data or spikes screw up our noise muffler. if (count < IgnoreHead || !(abs > 5 * average)) { average = (average * count + abs) / ++count; } else { count++; } } while (ie.MoveNext()); CassetteData[] output = new CassetteData[chunks.Count]; for (int i = 0; i < output.Length; ++i) { output[i] = chunks[i]; } return output; }
public void WriteCassetteData(CassetteData data, string location) { Stream stream = GetStream(location); BinaryWriter writer = new BinaryWriter(stream); Console.WriteLine(SAMPLE_RATE); int size = SAMPLE_RATE * 22 + (88 * data.Program.Length + 59888) * WRITE_RATE; // The "RIFF" chunk descriptor. writer.Write("RIFF".ToCharArray()); writer.Write((Int32) (36 + size)); writer.Write("WAVE".ToCharArray()); // The "fmt" sub-chunk. writer.Write("fmt ".ToCharArray()); writer.Write((Int32) 16); writer.Write((Int16) 1); writer.Write((Int16) 1); writer.Write((Int32) SAMPLE_RATE); writer.Write((Int32) SAMPLE_RATE * 2); writer.Write((Int16) 16); writer.Write((Int16) 16); // The "data" sub-chunk. writer.Write("data".ToCharArray()); writer.Write((Int32) size); // 10 Seconds for (int i = 0; i < SAMPLE_RATE * 10; ++i) { writer.Write((Int16) 0); } // 3600 Bits for (int i = 0; i < 3600; ++i) { Write(writer, true); } // 1 Byte. Write(writer, data.Meta.Key); char[] name = data.Meta.FileName.ToCharArray(); if (name.Length > 16) { throw new Exception("Filename of unexpected length."); } foreach (char c in name) { Write(writer, (byte) c); } // 16 Bytes. for (int i = name.Length; i < 16; ++i) { Write(writer, (byte) ' '); } // 3 Bytes. Write(writer, data.Meta.ProgramSize); Write(writer, data.Meta.Parity); // 2 Bytes. Write(writer, (byte) 0); Write(writer, (byte) 0); // 1 Second. for (int i = 0; i < SAMPLE_RATE; ++i) { writer.Write((Int16) 0); } // 3600 Bits. for (int i = 0; i < 3600; ++i) { Write(writer, true); } // 1 Byte. Write(writer, data.Program.Key); // Program.Length Bytes. foreach (byte b in data.Program) { Write(writer, b); } // 1 Byte. Write(writer, data.Program.Parity); // 2 Bytes. Write(writer, (byte) 0); Write(writer, (byte) 0); writer.Close(); stream.Close(); stream.Dispose(); }