public void Serialize(ref ulong i) { crc = CRC32.Compute(BitConverter.GetBytes(i), crc); }
public void Serialize(ref sbyte[] values) { crc = CRC32.Compute(BitConverter.GetBytes(values.Length), crc); crc = CRC32.Compute(values, crc); }
public void Serialize(ref sbyte b) { crc = CRC32.Compute((byte)b, crc); }
public void Serialize(ref byte b) { crc = CRC32.Compute(b, crc); }
public void Serialize(ref bool b) { crc = CRC32.Compute((byte)(b ? 1 : 0), crc); }
private int OutputInstruments() { // Process all envelope, make unique, etc. var uniqueEnvelopes = new SortedList <uint, byte[]>(); var instrumentEnvelopes = new Dictionary <Envelope, uint>(); var defaultEnv = new byte[] { 0xc0, 0x00, 0x00 }; var defaultEnvCRC = CRC32.Compute(defaultEnv); uniqueEnvelopes.Add(defaultEnvCRC, defaultEnv); foreach (var instrument in project.Instruments) { foreach (var env in instrument.Envelopes) { var processed = ProcessEnvelope(env); if (processed == null) { instrumentEnvelopes[env] = defaultEnvCRC; } else { uint crc = CRC32.Compute(processed); uniqueEnvelopes[crc] = processed; instrumentEnvelopes[env] = crc; } } } int size = 0; // Write instruments lines.Add($"{ll}instruments:"); for (int i = 0; i < project.Instruments.Count; i++) { var instrument = project.Instruments[i]; var volumeEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Volume]]); var arpeggioEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Arpeggio]]); var pitchEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Pitch]]); lines.Add($"\t{db} ${(instrument.DutyCycle << 6) | 0x30:x2} ;instrument {i:x2} ({instrument.Name})"); lines.Add($"\t{dw} {ll}env{volumeEnvIdx},{ll}env{arpeggioEnvIdx},{ll}env{pitchEnvIdx}"); lines.Add($"\t{db} $00"); size += 2 * 3 + 2; } lines.Add(""); // Write samples. lines.Add($"{ll}samples:"); if (project.UsesSamples) { for (int i = 1; i < project.SamplesMapping.Length; i++) { var mapping = project.SamplesMapping[i]; var sampleOffset = 0; var sampleSize = 0; var samplePitchAndLoop = 0; var sampleName = ""; if (mapping != null && mapping.Sample != null) { sampleOffset = project.GetAddressForSample(mapping.Sample) >> 6; sampleSize = mapping.Sample.Data.Length >> 4; sampleName = $"({mapping.Sample.Name})"; samplePitchAndLoop = mapping.Pitch | ((mapping.Loop ? 1 : 0) << 6); } lines.Add($"\t{db} ${sampleOffset:x2}+{lo}(FT_DPCM_PTR),${sampleSize:x2},${samplePitchAndLoop:x2}\t;{i} {sampleName}"); size += 3; } lines.Add(""); } // Write envelopes. int idx = 0; foreach (var env in uniqueEnvelopes.Values) { lines.Add($"{ll}env{idx++}:"); lines.Add($"\t{db} {String.Join(",", env.Select(i => $"${i:x2}"))}"); size += env.Length; } return(size); }
private int OutputInstruments() { // Process all envelope, make unique, etc. var uniqueEnvelopes = new SortedList <uint, byte[]>(); var instrumentEnvelopes = new Dictionary <Envelope, uint>(); var defaultEnv = new byte[] { 0xc0, 0x7f, 0x00, 0x00 }; var defaultPitchEnv = new byte[] { 0x00, 0xc0, 0x7f, 0x00, 0x01 }; var defaultEnvCRC = CRC32.Compute(defaultEnv); var defaultPitchEnvCRC = CRC32.Compute(defaultPitchEnv); var defaultEnvName = ""; var defaultPitchEnvName = ""; uniqueEnvelopes.Add(defaultEnvCRC, defaultEnv); if (kernel == FamiToneKernel.FamiTone2FS) { uniqueEnvelopes.Add(defaultPitchEnvCRC, defaultPitchEnv); } foreach (var instrument in project.Instruments) { for (int i = 0; i < Envelope.Max; i++) { var env = instrument.Envelopes[i]; var processed = ProcessEnvelope(env, i == Envelope.Volume && kernel == FamiToneKernel.FamiTone2FS, i == Envelope.Pitch && kernel == FamiToneKernel.FamiTone2FS); if (processed == null) { if (kernel == FamiToneKernel.FamiTone2FS && i == Envelope.Pitch) { instrumentEnvelopes[env] = defaultPitchEnvCRC; } else { instrumentEnvelopes[env] = defaultEnvCRC; } } else { uint crc = CRC32.Compute(processed); uniqueEnvelopes[crc] = processed; instrumentEnvelopes[env] = crc; } } } int size = 0; // Write instruments lines.Add($"{ll}instruments:"); for (int i = 0; i < project.Instruments.Count; i++) { var instrument = project.Instruments[i]; var volumeEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Volume]]); var arpeggioEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Arpeggio]]); var pitchEnvIdx = uniqueEnvelopes.IndexOfKey(instrumentEnvelopes[instrument.Envelopes[Envelope.Pitch]]); var dutyShift = instrument.ExpansionType == Project.ExpansionVrc6 ? 4 : 6; var dutyBits = instrument.ExpansionType == Project.ExpansionVrc6 ? 0 : 0x30; lines.Add($"\t{db} ${(instrument.DutyCycle << dutyShift) | dutyBits:x2} ;instrument {i:x2} ({instrument.Name})"); lines.Add($"\t{dw} {ll}env{volumeEnvIdx},{ll}env{arpeggioEnvIdx},{ll}env{pitchEnvIdx}"); lines.Add($"\t{db} $00"); size += 2 * 3 + 2; } lines.Add(""); // Write samples. lines.Add($"{ll}samples:"); if (project.UsesSamples) { for (int i = 1; i < project.SamplesMapping.Length; i++) { var mapping = project.SamplesMapping[i]; var sampleOffset = 0; var sampleSize = 0; var samplePitchAndLoop = 0; var sampleName = ""; if (mapping != null && mapping.Sample != null) { sampleOffset = project.GetAddressForSample(mapping.Sample) >> 6; sampleSize = mapping.Sample.Data.Length >> 4; sampleName = $"({mapping.Sample.Name})"; samplePitchAndLoop = mapping.Pitch | ((mapping.Loop ? 1 : 0) << 6); } lines.Add($"\t{db} ${sampleOffset:x2}+{lo}(FT_DPCM_PTR),${sampleSize:x2},${samplePitchAndLoop:x2}\t;{i} {sampleName}"); size += 3; } lines.Add(""); } // Write envelopes. int idx = 0; foreach (var kv in uniqueEnvelopes) { var name = $"{ll}env{idx++}"; lines.Add($"{name}:"); lines.Add($"\t{db} {String.Join(",", kv.Value.Select(i => $"${i:x2}"))}"); size += kv.Value.Length; if (kv.Key == defaultEnvCRC) { defaultEnvName = name; } if (kv.Key == defaultPitchEnvCRC) { defaultPitchEnvName = name; } } // Write the unique vibrato envelopes. if (kernel == FamiToneKernel.FamiTone2FS) { // Create all the unique vibrato envelopes. foreach (var s in project.Songs) { foreach (var c in s.Channels) { foreach (var p in c.Patterns) { for (int n = 0; n < s.PatternLength; n++) { var note = p.Notes[n]; if (note.HasVibrato) { if (note.VibratoDepth == 0 || note.VibratoSpeed == 0) { p.Notes[n].Vibrato = 0; vibratoEnvelopeNames[0] = defaultPitchEnvName; continue; } var env = Envelope.CreateVibratoEnvelope(note.VibratoSpeed, note.VibratoDepth); var processed = ProcessEnvelope(env, false, true); uint crc = CRC32.Compute(processed); if (!uniqueEnvelopes.ContainsKey(crc)) { var name = $"{ll}env{idx++}"; lines.Add($"{name}:"); lines.Add($"\t{db} {String.Join(",", processed.Select(i => $"${i:x2}"))}"); size += env.Length; uniqueEnvelopes[crc] = processed; vibratoEnvelopeNames[note.Vibrato] = name; } } } } } } } return(size); }