public static void AddNew(Song currentSong) { Instrument nuevo = new Instrument(); nuevo.SetVolumeLength(5); nuevo.Name = WYZTracker.Core.Properties.Resources.New; nuevo.Looped = false; nuevo.Volumes = new byte[] { 8, 8, 8, 8, 8 }; nuevo.ID = currentSong.Instruments.GetSafeId().ToString(); currentSong.Instruments.Add(nuevo); }
public static void AddNew(Song currentSong) { Effect nuevo = new Effect(); nuevo.SetEffectLength(5); nuevo.Name = WYZTracker.Core.Properties.Resources.New; nuevo.Volumes = new byte[] { 8, 8, 8, 8, 8 }; nuevo.Frequencies = new int[] { 440, 440, 440, 440, 440 }; nuevo.Noises = new byte[] { 0, 1, 2, 3, 4 }; nuevo.ID = currentSong.Effects.GetSafeId(); currentSong.Effects.Add(nuevo); }
public static void Import(Song currentSong) { Instruments loadedInstruments = null; OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = WYZTracker.Core.Properties.Resources.INSFilter; if (ofd.ShowDialog() == DialogResult.OK) { XmlSerializer formatter = new XmlSerializer(typeof(Instruments)); Stream objFileStream = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read, FileShare.None); try { loadedInstruments = (Instruments)formatter.Deserialize(objFileStream); } catch { try { formatter = new XmlSerializer(typeof(Song)); objFileStream.Seek(0, SeekOrigin.Begin); objFileStream = SongManager.GetStream(objFileStream); loadedInstruments = ((Song)formatter.Deserialize(objFileStream)).Instruments; } catch { loadedInstruments = null; } } objFileStream.Close(); } if (loadedInstruments != null) { foreach (Instrument i in loadedInstruments) { if (i.ID != "R") { i.ID = currentSong.Instruments.GetSafeId().ToString(); currentSong.Instruments.Add(i); } } } }
public static void Import(Song currentSong) { Effects loadedFX = null; OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = WYZTracker.Core.Properties.Resources.FXFilter; if (ofd.ShowDialog() == DialogResult.OK) { XmlSerializer formatter = new XmlSerializer(typeof(Effects)); Stream objFileStream = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read, FileShare.None); try { loadedFX = (Effects)formatter.Deserialize(objFileStream); } catch { try { formatter = new XmlSerializer(typeof(Song)); objFileStream.Seek(0, SeekOrigin.Begin); objFileStream = SongManager.GetStream(objFileStream); loadedFX = ((Song)formatter.Deserialize(objFileStream)).Effects; } catch { loadedFX = null; } } objFileStream.Close(); } if (loadedFX != null) { foreach (Effect fx in loadedFX) { fx.ID = currentSong.Effects.GetSafeId(); currentSong.Effects.Add(fx); } } }
public static void SaveSong(Song currentSong, string fileName) { XmlSerializer formatter = new XmlSerializer(typeof(Song)); Stream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); GZipStream gzip = new GZipStream(fileStream, CompressionMode.Compress, true); formatter.Serialize(gzip, currentSong); gzip.Flush(); gzip.Close(); fileStream.Close(); fileStream.Dispose(); }
public static void Remove(Song currentSong, Instrument instrument) { currentSong.Instruments.Remove(instrument); }
public static void Export(Song currentSong) { Export(currentSong.Instruments); }
private void initializeTestSong() { testSong = new Song(this.currentSong.Channels); testSong.Tempo = this.currentSong.Tempo; testSong.Instruments = currentSong.Instruments; testSong.Effects = currentSong.Effects; testSong.Frequencies = currentSong.Frequencies; testSong.ChipFrequency = currentSong.ChipFrequency; testSong.PlayOrder.Clear(); testSong.PlayOrder.Add(0); buildTestPattern(); songPlayer.CurrentSong = testSong; }
public static byte[] GenerateSong(Song song) { List<byte> bytes = new List<byte>(); Pattern current; ChannelNote note; int noteLen; bool lastNoteSilence; string[] lastInstrument = new string[song.Channels]; EnvelopeData[] lastEnvelopes = new EnvelopeData[song.Channels]; int[] loopLocations = new int[song.Channels + 1]; int d; int dSeminote; int o; bytes.Add(song.Tempo); byte headerByte = (byte)(song.Looped ? 0x01 : 0x00); headerByte |= (byte)((song.FxChannel & 0x7) << 1); headerByte |= (byte)((song.Channels & 0x7) << 4); bytes.Add(headerByte); // Dos bytes reservados (de momento). bytes.Add(0); bytes.Add(0); // Metemos los bytes de offset de loops. int offsetLoopLocations = bytes.Count; bytes.AddRange(new byte[2 * (song.Channels + 1)]); for (int currentChannel = 0; currentChannel < song.Channels; currentChannel++) { lastInstrument[currentChannel] = string.Empty; lastEnvelopes[currentChannel] = null; } List<string> notesWithTempoModifier = new List<string>(); for (int currentChannel = 0; currentChannel < song.Channels; currentChannel++) { noteLen = 0; lastNoteSilence = false; o = 0; d = 0; dSeminote = 0; sbyte? volModifier = null; sbyte tempoModifier; List<byte> bytesPatron = new List<byte>(); bool calculatingFirstNoteOffset = false; int firstNoteOffsetInLoopToPattern = -1; for (int currentPattern = 0; currentPattern < song.PlayOrder.Count; currentPattern++) { current = song.Patterns[song.PlayOrder[currentPattern]]; if (song.Looped && currentPattern == song.LoopToPattern) { calculatingFirstNoteOffset = true; firstNoteOffsetInLoopToPattern = 0; } for (int currentLine = 0; currentLine < current.Length; currentLine++) { ChannelLine line = current.Lines[currentLine]; note = line.Notes[currentChannel]; tempoModifier = 0; if (note.HasValue) { if (noteLen > 0) { noteLen = addNote(bytesPatron, noteLen, lastNoteSilence, d, dSeminote, o); } if (calculatingFirstNoteOffset && song.Looped) { loopLocations[currentChannel] = bytesPatron.Count; // + bytesAntesDeInstrumento.Count; firstNoteOffsetInLoopToPattern += currentLine; calculatingFirstNoteOffset = false; } } if (note.HasOctave) { o = note.Octave - 2; } if (note.HasNote) { dSeminote = 0; if (note.Note == 'P') { lastNoteSilence = true; } else { lastNoteSilence = false; d = getNote(note.Note); } volModifier = note.VolModifier; string key = string.Format("{0}_{1}", currentPattern, currentLine); if (!notesWithTempoModifier.Contains(key)) { tempoModifier = line.TempoModifier; if (tempoModifier != 0) { notesWithTempoModifier.Add(key); } } else { tempoModifier = 0; } } if (note.HasSeminote) { if (note.Seminote == '+') dSeminote = 1; else dSeminote = -1; } if (note.HasInstrument || note.VolModifier.HasValue || tempoModifier != 0) { if (note.VolModifier.HasValue || note.Instrument != lastInstrument[currentChannel] || (note.IsSawtooth && !EnvelopeData.Compare(note.EnvData, lastEnvelopes[currentChannel]))) { if (note.Instrument.ToUpper() == "R") { bytesPatron.Add(0xbf); bytesPatron.Add(getSawtoothParamsByte(note)); lastEnvelopes[currentChannel] = note.EnvData; } else { bytesPatron.Add(0x3f); bytesPatron.Add(note.HasInstrument ? byte.Parse(note.Instrument) : byte.Parse(lastInstrument[currentChannel])); byte tModifier = tempoModifier == -1 ? (byte)(1 << 5) : tempoModifier == 1 ? (byte)(1 << 6) : (byte)0; byte modifiers = (byte)((note.VolModifier.GetValueOrDefault() & 0x1F) | tModifier); bytesPatron.Add(modifiers); lastEnvelopes[currentChannel] = null; } if (note.HasInstrument) { lastInstrument[currentChannel] = note.Instrument; } } } noteLen++; } // Calculamos la longitud de la última nota haciendo que añada la longitud del canal actual completo // si en este canal no hay notas, a la espera de encontrar una nota en este canal. if (calculatingFirstNoteOffset) { firstNoteOffsetInLoopToPattern += current.Length; } } if (noteLen > 0 && bytesPatron.Count > 0) { noteLen = addNote(bytesPatron, noteLen + ((song.Looped && firstNoteOffsetInLoopToPattern >= 0) ? firstNoteOffsetInLoopToPattern : 0), lastNoteSilence, d, dSeminote, o); } // Si no se ha encontrado aún una nota a la que saltar cuando hay loop, entonces el salto del loop es // al final del canal. if (calculatingFirstNoteOffset) { loopLocations[currentChannel] = bytesPatron.Count; } if (bytesPatron.Count == 0) { bytesPatron.Add(0xC1); } bytes.AddRange(bytesPatron); bytes.Add(0x00); // Fin de canal. } // Canal de FX!!! List<byte> bytesFX = new List<byte>(); int currentFx = int.MinValue; noteLen = 0; bool calculatingFirstFxOffset = false; int firstFxOffsetInLoopToPattern = -1; for (int currentPattern = 0; currentPattern < song.PlayOrder.Count; currentPattern++) { if (song.Looped && currentPattern == song.LoopToPattern) { calculatingFirstFxOffset = true; firstFxOffsetInLoopToPattern = 0; } current = song.Patterns[song.PlayOrder[currentPattern]]; for (int currentNote = 0; currentNote < current.Length; currentNote++) { // Ver cómo se tiene que generar los FX. if (current.Lines[currentNote].Fx != int.MinValue && noteLen > 0) { noteLen = addFX(bytesFX, noteLen, currentFx, song); } if (current.Lines[currentNote].Fx != int.MinValue) { currentFx = current.Lines[currentNote].Fx; if (song.Looped && calculatingFirstFxOffset) { calculatingFirstFxOffset = false; firstFxOffsetInLoopToPattern += currentNote; loopLocations[song.Channels] = bytesFX.Count; } } noteLen++; } if (calculatingFirstFxOffset) { firstFxOffsetInLoopToPattern += current.Length; } } if (noteLen > 0 && currentFx >= 0) { noteLen = addFX(bytesFX, noteLen + ((song.Looped && firstFxOffsetInLoopToPattern >= 0) ? firstFxOffsetInLoopToPattern : 0), currentFx, song); } if (calculatingFirstFxOffset) { loopLocations[song.Channels] = bytesFX.Count; } if (bytesFX.Count == 0) { bytesFX.Add(0xC1); } bytes.AddRange(bytesFX); bytes.Add(0x00); // Fin de canal. bytes.Add(0x00); // Fin de canción. (¿¿Hace falta??) for (int c = 0; c <= song.Channels; ++c) { bytes[offsetLoopLocations + 2 * c] = (byte)(loopLocations[c] & 0x00FF); bytes[offsetLoopLocations + (2 * c) + 1] = (byte)((loopLocations[c] & 0x0FF00) >> 8); } return bytes.ToArray(); }
private static StringBuilder generarTablaPautas(Song song) { StringBuilder sbTablaPautas = new StringBuilder(); sbTablaPautas.AppendLine(); sbTablaPautas.AppendLine("; Tabla de instrumentos"); sbTablaPautas.Append("TABLA_PAUTAS: DW "); if (song.Instruments.Count == 0) { sbTablaPautas.Append("0,"); } else { Dictionary<int, Instrument> instrumentTable = new Dictionary<int, Instrument>(); int maxId = int.MinValue; foreach (Instrument i in song.Instruments) { int id; if (int.TryParse(i.ID, out id)) { instrumentTable.Add(id, i); if (id > maxId) { maxId = id; } } } for (int instrumentId = 0; instrumentId <= maxId; instrumentId++) { if (instrumentTable.ContainsKey(instrumentId)) { string nombrePauta = string.Format("PAUTA_{0}", instrumentId); sbTablaPautas.AppendFormat("{0},", nombrePauta); } else { sbTablaPautas.Append("0,"); } } } sbTablaPautas.Length--; sbTablaPautas.AppendLine(); return sbTablaPautas; }
private static StringBuilder generarTablaEfectos(Song song) { StringBuilder sbTablaEfectos = new StringBuilder(); sbTablaEfectos.AppendLine(); sbTablaEfectos.AppendLine("; Tabla de efectos"); sbTablaEfectos.Append("TABLA_SONIDOS: DW "); if (song.Effects.Count == 0) { sbTablaEfectos.Append("0,"); } else { Dictionary<int, Effect> effectTable = new Dictionary<int, Effect>(); int maxId = int.MinValue; foreach (Effect e in song.Effects) { effectTable.Add(e.ID, e); if (e.ID > maxId) { maxId = e.ID; } } for (int fxId = 0; fxId <= maxId; fxId++) { if (effectTable.ContainsKey(fxId)) { string nombreEfecto = string.Format("SONIDO{0}", fxId); sbTablaEfectos.AppendFormat("{0},", nombreEfecto); } else { sbTablaEfectos.Append("0,"); } } } sbTablaEfectos.Length--; sbTablaEfectos.AppendLine(); return sbTablaEfectos; }
private static int addFX(List<byte> bytesFX, int noteLen, int currentFx, Song song) { int l; int w = 0; if (noteLen > 0) { l = getLength(ref noteLen); if (currentFx != int.MinValue) { bytesFX.Add(0x7F); w = 0x40 * l + currentFx; } else { w = 0x40 * l + 1; } bytesFX.Add((byte)w); while (noteLen > 0) { if (noteLen >= longitudPuntillo[l]) { while (noteLen >= longitudPuntillo[l]) { w = 0x40 * l + 0x3E; bytesFX.Add((byte)w); noteLen -= longitudPuntillo[l]; } } else { l = getLength(ref noteLen); bytesFX.Add((byte)(0x40 * l + 1)); } } } return noteLen; }
public static string GenerateInstrumentsAndFX(Song song) { int i = 0; StringBuilder sb = new StringBuilder(); StringBuilder sbTablaPautas = generarTablaPautas(song); StringBuilder sbTablaEfectos = generarTablaEfectos(song); sb.AppendLine(); sb.AppendLine(";Pautas (instrumentos)"); for (i = 0; i < song.Instruments.Count; i++) { Instrument inst = song.Instruments[i]; if (inst.ID != "R") { sb.AppendFormat(";Instrumento '{0}'", inst.Name.Replace(':','-')); sb.AppendLine(); string nombrePauta = string.Format("PAUTA_{0}", inst.ID); sb.AppendFormat("{0}:\tDB\t", nombrePauta); for (int j = 0; j < inst.Volumes.Length; j++) { sb.AppendFormat("{0},{1},", inst.Volumes[j], inst.PitchModifiers[j]); } if (inst.Looped) { sb.AppendFormat("{0}", 0x80 + inst.Volumes.Length - inst.LoopStart); } else { sb.AppendFormat("0,{0}", 0x80 + 1); } sb.AppendLine(); } } sb.AppendLine(); sb.AppendLine(";Efectos"); for (i = 0; i < song.Effects.Count; i++) { Effect eff = song.Effects[i]; sb.AppendFormat(";Efecto '{0}'", eff.Name.Replace(':','-')); sb.AppendLine(); string nombreEfecto = string.Format("SONIDO{0}", eff.ID); sb.AppendFormat("{0}:\tDB\t", nombreEfecto); for (int k = 0; k < eff.Volumes.Length; k++) { bool hasEnv = ((eff.Noises[k] & 0x80) == 0x80); sb.AppendFormat("{0},{1},{2},", (eff.Frequencies[k] & 0xFF), ((eff.Frequencies[k] & 0x0F00) >> 4) + eff.Volumes[k], eff.Noises[k]); if (hasEnv) { sb.AppendFormat("{0},{1},{2},", eff.EnvFreqs[k] & 0xFF, (eff.EnvFreqs[k] & 0x0F00) >> 8, eff.EnvTypes[k]); } } sb.Append("255"); sb.AppendLine(); } sb.AppendLine(); sb.AppendLine(";Frecuencias para las notas"); sb.AppendLine("DATOS_NOTAS: DW 0,0"); for (i = 0; i < 6; i++) { int baseIdx = (i * 10) + 2; sb.Append("DW "); for (int j = 0; j < 10; j++) { sb.AppendFormat("{0},", song.Frequencies[baseIdx + j]); } sb.Length--; sb.AppendLine(); } sb.Insert(0, sbTablaEfectos.ToString()); sb.Insert(0, sbTablaPautas.ToString()); return sb.ToString(); }
public static void Remove(Song currentSong, Effect effect) { currentSong.Effects.Remove(effect); }
public static void Export(Song currentSong) { Export(currentSong.Effects); }