static void CreateTestWAV() { Console.Write("Creating test.wav..."); opl3 opl = new opl3(); opl.OPL3_WriteRegBuffered(0x01, 0x20); //set WSE=1 waveheader head = new waveheader(); Int16[] buffer = new Int16[opl.SampleRate * 2]; //Muliply by 2 since it's stereo so 2 channels using (FileStream fout = File.OpenWrite("test.wav")) { //write dummy wave header: fout.Write(head.ToByteArray(), 0, 46); //Command OPL to generate sound //Commands taken from "Making a Sound" section of http://shipbrook.net/jeff/sb.html opl.OPL3_WriteRegBuffered(0x20, 0x01); opl.OPL3_WriteRegBuffered(0x40, 0x10); opl.OPL3_WriteRegBuffered(0x60, 0xF0); opl.OPL3_WriteRegBuffered(0x80, 0x77); opl.OPL3_WriteRegBuffered(0xA0, 0x98); opl.OPL3_WriteRegBuffered(0x23, 0x01); opl.OPL3_WriteRegBuffered(0x43, 0x00); opl.OPL3_WriteRegBuffered(0x63, 0xF0); opl.OPL3_WriteRegBuffered(0x83, 0x77); opl.OPL3_WriteRegBuffered(0xB0, 0x31); opl.OPL3_GenerateStream(buffer, opl.SampleRate * 1); //generate 1 second worth of samples fout.Write(GetBufferBytes(buffer), 0, (buffer.Length * sizeof(Int16))); fout.Flush(); uint size = (uint)fout.Position; //fill header with correct values: head.dSize = size - 46; head.rSize = size - 8; head.fHertz = opl.SampleRate; head.fBlockAlign = (ushort)(head.fChannels * (head.fBits / 8)); head.fBytesPerSec = head.fBlockAlign * opl.SampleRate; //write real wave header: fout.Seek(SEEK_SET, SeekOrigin.Begin); fout.Write(head.ToByteArray(), 0, 46); fout.Flush(); } opl.OPL3_Reset(); Console.WriteLine("done!"); return; }
public static void ConvertImf2Wav(string ImfFilePath, string WavFilePath) { Console.Write("Converting " + Path.GetFileName(ImfFilePath) + " to WAV..."); opl3 opl; waveheader head = new waveheader(); UInt32 imf_rate = 560, wav_rate = DEF_FREQ, samples_per_tick; imf_rate = 700; samples_per_tick = wav_rate / imf_rate; //if(YM3812Init(1, YM3812_RATE, wav_rate)) //{ // printf("Unable to create virtual OPL!!\n"); // return 1; //} opl = new opl3(wav_rate, 2); opl.OPL3_WriteRegBuffered(1, 0x20); //set WSE=1 using (FileStream fin = File.OpenRead(ImfFilePath)) { UInt32 size, cnt = 0, imfsize = 0xFFFFFFFF; bool has_notes = false; if (IMF_IsChunk(fin)) { UInt16 size1 = ReadInt16LE(fin); //Console.WriteLine("IMF size is " + size1 + " Bytes."); imfsize = (uint)(size1 >> 2); } else { //Console.WriteLine("IMF size is not set."); } //Console.WriteLine("IMF rate is " + imf_rate + " Hz."); //printf("Channel mask is 0x%X\n", channel_mask); Int16[] buffer = new Int16[samples_per_tick * 2]; //Console.WriteLine("buffer allocated.\n"); //out = fopen(wavefile, "wb"); //if (out) using (FileStream fout = File.OpenWrite(WavFilePath)) { UInt16 imfdelay, imfcommand; //printf("%s opened for output.\n", wavefile); //Console.WriteLine("Converting IMF data to PCM data\n"); //write dummy wave header: fout.Write(head.ToByteArray(), 0, 46); int totalsamples = 0; //write converted PCM data: while (imfsize > 0) { imfsize--; try { imfcommand = ReadInt16LE(fin); imfdelay = ReadInt16LE(fin); } catch { break; } opl.OPL3_WriteRegBuffered((ushort)(imfcommand & 0xFF), (byte)((imfcommand >> 8) & 0xFF)); while (imfdelay-- > 0) { opl.OPL3_GenerateStream(buffer, samples_per_tick); fout.Write(GetBufferBytes(buffer), 0, buffer.Length * sizeof(Int16)); fout.Flush(); totalsamples += (int)samples_per_tick; } //if (!(cnt++ & 0xff)) //{ // printf("."); // fflush(stdout); //} } //Console.WriteLine("done!"); //else //{ // printf("ERROR: could not write %s\n", wavefile); //} //size = ftell(out); size = (uint)fout.Position; //fill header with correct values: head.dSize = size - 46; head.rSize = size - 8; head.fHertz = wav_rate; head.fBlockAlign = (ushort)(head.fChannels * (head.fBits / 8)); head.fBytesPerSec = head.fBlockAlign * wav_rate; //write real wave header: fout.Seek(SEEK_SET, SeekOrigin.Begin); fout.Write(head.ToByteArray(), 0, 46); fout.Flush(); } //if (!has_notes) //{ // printf("The song did not play any notes.\n"); // exit(1); //} //fclose(in); } //YM3812Shutdown(); opl.OPL3_Reset(wav_rate); Console.WriteLine("done!"); return; }
/* public WavReader(Stream t,long startpos) * { * daten = new BufferedStream(t,1677216); * this.startpos = startpos; * reader = new BinaryReader(daten); * t.Seek(startpos,SeekOrigin.Begin ); * this.startpos += 44;// die 1. 44 bytes sollen nicht lesbar sein * position = 0; * header=new waveheader(); * byte[] tmp; * tmp = reader.ReadBytes(44); * int zuskippen = 44; * int i; * unsafe * { * fixed (waveheader* pointer = &header) * { * byte* bytepointer = (byte*)pointer; * for (i = 0; i < 44; i++) * { *(bytepointer + i) = tmp[i]; * } * } * } * * if ((header.bitspersample != 16) || (header.formattag != 1)) * { * throw new ArgumentException("Die Wavdaten sind nicht mit 16bit Samples oder nicht in PCM kodiert"); * } * waveheader h = header; * MessageBox.Show("bitps: " + h.bitspersample + "\nBlockal: " + h.blockalign + "\nBytps: " + h.bytespersecond + "\nChannels: " + h.channels + "\nData: " + h.data + "\nDatal: " + h.datalength + "\nFilesize: " + h.filesize + "\nFmt: " + h.fmt + "\nFmtl: " + h.fmtlength + "\nFormattag: " + h.formattag + "\nRiff: " + h.riff + "\nSamplerate: " + h.samplerate + "\nWave: " + h.wave + " "); * laenge = header.filesize+8-44; * }*/ public WavReader(Stream t, long startpos) { daten = new BufferedStream(t, 1677216); daten.Seek(startpos, SeekOrigin.Begin); reader = new BinaryReader(daten); uint zuskippen = 0; this.startpos = startpos; header = new waveheader(); chunk ch = new chunk(); do { //MessageBox.Show("Header lesend..."); ch.header = (uint)reader.ReadInt32(); ch.laenge = (uint)reader.ReadInt32(); //MessageBox.Show("Chunk gelesen..."); zuskippen += 8; // MessageBox.Show(""+ch.laenge+" "+ch.header); if (ch.header == 1179011410) { //MessageBox.Show("RIFF gefunden"); header.riff = ch.header; header.filesize = ch.laenge; header.wave = (uint)reader.ReadInt32(); zuskippen += 4; } else if (ch.header == 544501094)//fmt //MessageBox.Show("FMT gefunden "+ch.laenge); { int i; unsafe { fixed(waveheader *headerpointer = &header) { byte *zieladdr = (byte *)headerpointer; for (i = 20; i < 36; i++) { *(zieladdr + i) = reader.ReadByte(); } } } if (ch.laenge > 16) { reader.ReadBytes((int)(ch.laenge - 16)); } header.fmt = ch.header; header.fmtlength = ch.laenge; zuskippen += ch.laenge; } else if (ch.header == 1635017060) { // MessageBox.Show("DATA gefunden"); header.data = ch.header; header.datalength = ch.laenge; break; } else { // MessageBox.Show("WTF gefunden (wahrscheinlich list) "+ch.header+" "+ch.laenge); zuskippen += ch.laenge; reader.ReadBytes((int)ch.laenge); } }while(true); waveheader h = header; // MessageBox.Show("bitps: " + h.bitspersample + "\nBlockal: " + h.blockalign + "\nBytps: " + h.bytespersecond + "\nChannels: " + h.channels + "\nData: " + h.data + "\nDatal: " + h.datalength + "\nFilesize: " + h.filesize + "\nFmt: " + h.fmt + "\nFmtl: " + h.fmtlength + "\nFormattag: " + h.formattag + "\nRiff: " + h.riff + "\nSamplerate: " + h.samplerate + "\nWave: " + h.wave + " "); laenge = header.filesize + 8 - zuskippen; this.startpos += zuskippen; position = 0; seek(); }