public void SaveWAV() { if (m_OperationInProgress) { return; } if (m_WavSave.ShowDialog()) { StartCoroutine(SaveWAVRoutine(m_WavSave.OpenFile( ), true)); } }
IEnumerator SaveVGMRoutine(TinyFileDialogs.SaveFileDialog sfd) { playback.Stop( ); playback.psg.audioSource.enabled = false; playback.follow = false; data.currentPattern = 0; m_OperationInProgress = true; bool isCompressed = sfd.filePath.Contains(".vgz"); Stream fileStream = isCompressed ? new MemoryStream( ) : sfd.OpenFile( ); BinaryWriter bw = new BinaryWriter(fileStream); bw.Write(Encoding.ASCII.GetBytes("Vgm ")); //0x00 //wrote eof offset later when we know 0x04 bw.Seek(0x08, SeekOrigin.Begin); bw.Write(( uint )0x00000170); //0x08 bw.Write(( uint )playback.psg.chip.clock); //0x0C //gd3???? 0x14 //write wait values later when we know 0x18 //implement loop offset some rainy day 0x1C + 0x20 bw.Seek(0x24, SeekOrigin.Begin); bw.Write(( uint )playback.playbackRate); //0x24 bw.Write(( ushort )SN76489.NOISE_TAPPED); //0x28 bw.Write(( byte )(SN76489.NOISE_SR_WIDTH + 1)); //0x2A bw.Write(( byte )0x00); bw.Seek(0x34, SeekOrigin.Begin); bw.Write(( uint )0x0C); bw.Seek(0x40, SeekOrigin.Begin); List <PSGWrapper.RegisterWrite> dataSamples = playback.psg.RecordRegisters( ); playback.Play(false); int c = 0; while (playback.isPlaying) { playback.psg.ManualClock( ); m_Progress = playback.songProgress * 50; c++; if (c > 44100) { c = 0; yield return(null); } } playback.psg.RecordRegisters(false); playback.psg.ResetChip( ); int loopWaitAmount = 0; int waitAmount = 0; int loopOffset = 0x40; int bytesWritten = 0; bool foundLoop = false; for (int i = 0; i < dataSamples.Count; i++) { if (dataSamples [i].wait > 0) { switch (dataSamples [i].wait) { case 735: bw.Write(( byte )VGMCommands.Wait735); bytesWritten++; break; case 882: bw.Write(( byte )VGMCommands.Wait882); bytesWritten++; break; default: int totalWait = dataSamples [i].wait; do { bw.Write(( byte )VGMCommands.WaitSamples); bw.Write(( ushort )System.Math.Min(65535, totalWait)); totalWait -= 65535; bytesWritten += 3; } while (totalWait > 65535); break; } if (dataSamples [i].pattern >= playback.patternLoop) { loopWaitAmount += dataSamples [i].wait; } waitAmount += dataSamples [i].wait; c++; if (c > 44100) { c = 0; yield return(null); } m_Progress = 50 + (( float )i / dataSamples.Count) * 50; } bw.Write(( byte )dataSamples [i].command); bytesWritten++; if (dataSamples [i].command != VGMCommands.EOF) { bw.Write(( byte )dataSamples [i].data); bytesWritten++; } if (dataSamples [i].pattern == playback.patternLoop && i == 0) { foundLoop = true; } if (!foundLoop && dataSamples [i].pattern == playback.patternLoop) { loopOffset += bytesWritten; foundLoop = true; } } //bw.Write((byte)0x66); int gd3Offset = ( int )bw.BaseStream.Position - 0x14; bw.Write(Encoding.ASCII.GetBytes("Gd3 ")); bw.Write(( uint )0x00010000); int sizeOffset = ( int )bw.BaseStream.Position; bw.Write(( uint )0); bw.Write(Encoding.Unicode.GetBytes(SongData.songName + "\0")); //track name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes("\0")); //game name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes("Sega Game Gear\0")); //system name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes(SongData.artistName + "\0")); //artist name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes(System.DateTime.Today.ToString(@"yyyy\/MM\/dd") + "\0")); //release date bw.Write(Encoding.Unicode.GetBytes("SnoozeTracker\0")); //converter bw.Write(Encoding.Unicode.GetBytes("https://github.com/tEFFx/SnoozeTracker\0")); //notes int eofOffset = ( int )bw.BaseStream.Position - 0x04; bw.Seek(sizeOffset, SeekOrigin.Begin); bw.Write(( uint )(eofOffset - sizeOffset)); bw.Seek(0x04, SeekOrigin.Begin); bw.Write(( uint )(eofOffset)); bw.Seek(0x14, SeekOrigin.Begin); bw.Write(( uint )(gd3Offset)); bw.Seek(0x18, SeekOrigin.Begin); bw.Write(( uint )waitAmount); if (playback.patternLoop != 0) { bw.Write(( uint )(loopOffset - 0x1C)); bw.Write(( uint )(loopWaitAmount)); } if (isCompressed) { Stream fs = sfd.OpenFile( ); GZipStream gzipStream = new GZipStream(fs, CompressionMode.Compress, CompressionLevel.BestCompression, true); byte [] buffer = new byte [fileStream.Length]; fileStream.Position = 0; fileStream.Read(buffer, 0, ( int )fileStream.Length); gzipStream.Write(buffer, 0, ( int )fileStream.Length); gzipStream.Close( ); } bw.Close( ); playback.psg.audioSource.enabled = true; playback.psg.enabled = false; playback.psg.enabled = true; playback.follow = true; m_OperationInProgress = false; playback.Stop( ); }
public void SaveFile(bool saveAs = true) { playback.Stop( ); if (!saveAs && (m_OpenFile == "" || !File.Exists(m_OpenFile))) { saveAs = true; } if (!saveAs || m_TuneSave.ShowDialog()) { SongFile song = new SongFile( ); song.patternLength = data.patternLength; song.lookupTable = data.lookupTable; song.transposeTable = data.transposeTable; song.songData = data.songData; int presetCount = instruments.presets.Length; song.instruments = new Instruments.InstrumentInstance [presetCount]; Array.Copy(instruments.presets, song.instruments, presetCount); song.songName = SongData.songName; song.artistName = SongData.artistName; IFormatter formatter = new BinaryFormatter(); Stream fs = !saveAs ? new FileStream(m_OpenFile, FileMode.Create) : m_TuneSave.OpenFile( ); formatter.Serialize(fs, song); fs.Close( ); if (saveAs) { m_OpenFile = m_TuneSave.filePath; } fileModified = false; } }