private void OPL4Write(ChipDatum dat) { //Log.WriteLine(LogLevel.TRACE, string.Format("FM P{2} Out:Adr[{0:x02}] val[{1:x02}]", (int)dat.address, (int)dat.data, dat.port)); //Console.WriteLine("FM P{2} Out:Adr[{0:x02}] val[{1:x02}]", (int)dat.address, (int)dat.data, dat.port); outDatum od = null; if (pcmdata.Count > 0) { chipRegister.YMF278BSetRegister(od, count, 0, pcmdata.ToArray()); pcmdata.Clear(); } if (dat.addtionalData != null) { if (dat.addtionalData is MmlDatum) { MmlDatum md = (MmlDatum)dat.addtionalData; if (md.linePos != null) { md.linePos.srcMMLID = filename; } od = new outDatum(md.type, md.args, md.linePos, (byte)md.dat); } } //if (od != null && od.linePos != null) //{ //Console.WriteLine("{0}", od.linePos.col); //} //chipRegister.YM2608SetRegister(od, (long)dat.time, 0, dat.port, dat.address, dat.data); chipRegister.YMF278BSetRegister(od, count, 0, dat.port, dat.address, dat.data); }
public MmlDatum ToMmlDatumn() { MmlDatum md = new MmlDatum(); md.args = this.args; md.dat = this.dat; md.linePos = this.linePos; md.type = this.type; return(md); }
private Func <object> vsetm() { pw.partWk[r.di].volume = r.al; //IDE向け ChipDatum cd = new ChipDatum(-1, -1, -1); MmlDatum md = new MmlDatum(-1, enmMMLType.Volume, pw.cmd.linePos, (int)r.al); cd.addtionalData = md; pmd.WriteDummy(cd); return(null); }
public void MWRIT2(MmlDatum dat) { //Console.WriteLine("{0:x2}", dat.dat); mucInfo.bufDst.Set(work.MDATA++, dat); if (work.MDATA - work.bufStartPtr > 0xffff) { throw new MucException( msg.get("E0200") , mucInfo.row, mucInfo.col); } muc88.DispHex4(work.MDATA, 36); }
private int P86Write(ChipDatum arg) { if (arg == null) { return(0); } if (!initPhase) { outDatum od = null; if (arg.addtionalData != null) { if (arg.addtionalData is MmlDatum) { MmlDatum md = (MmlDatum)arg.addtionalData; if (md.linePos != null) { md.linePos.srcMMLID = filename; } od = new outDatum(md.type, md.args, md.linePos, (byte)md.dat); } } if (arg.port == 0x00) { chipRegister.P86LoadPcm(od, count, 0, (byte)arg.address, (byte)arg.data, (byte[])arg.addtionalData); } else { chipRegister.P86Write(od, count, 0, arg.port, arg.address, arg.data); } return(0); } SoundManager.PackData p; if (arg.port == 0x00) { p = new SoundManager.PackData( null, null, EnmDataType.Block, arg.address, arg.data, arg.addtionalData); } else { p = new SoundManager.PackData( null, null, EnmDataType.Normal, arg.port, arg.address, arg.data); } p8d.Add(p); return(0); }
private static void OPNAWrite(ChipDatum dat) { if (dat != null && dat.addtionalData != null) { MmlDatum md = (MmlDatum)dat.addtionalData; if (md.linePos != null) { Log.WriteLine(LogLevel.TRACE, string.Format("! r{0} c{1}" , md.linePos.row , md.linePos.col )); } } //Log.WriteLine(LogLevel.TRACE, string.Format("FM P{2} Out:Adr[{0:x02}] val[{1:x02}]", (int)dat.address, (int)dat.data,dat.port)); mds.WriteYM2608(0, (byte)dat.port, (byte)dat.address, (byte)dat.data); }
public void MWRITE(MmlDatum cmdNo, MmlDatum cmdDat) { //Common.WriteLine("{0:x2}", cmdNo); mucInfo.bufDst.Set(work.MDATA++, cmdNo); //Common.WriteLine("{0:x2}", cmdDat); mucInfo.bufDst.Set(work.MDATA++, cmdDat); if (work.MDATA - work.bufStartPtr > 0xffff) { throw new MucException( msg.get("E0200") , mucInfo.row, mucInfo.col); } muc88.DispHex4(work.MDATA, 36); }
private static void OPNAWrite(ChipDatum dat) { if (dat != null && dat.addtionalData != null) { MmlDatum md = (MmlDatum)dat.addtionalData; if (md.linePos != null) { Log.WriteLine(LogLevel.TRACE, string.Format("! r{0} c{1}" , md.linePos.row , md.linePos.col )); } } vw.WriteYM2608(0, (byte)dat.port, (byte)dat.address, (byte)dat.data); }
private static void OPNBWrite(int chipId, ChipDatum dat) { if (dat != null && dat.addtionalData != null) { MmlDatum md = (MmlDatum)dat.addtionalData; if (md.linePos != null) { Log.WriteLine(LogLevel.TRACE, string.Format("! OPNB i{0} r{1} c{2}" , chipId , md.linePos.row , md.linePos.col )); } } Log.WriteLine(LogLevel.TRACE, string.Format("Out ChipB:{0} Port:{1} Adr:[{2:x02}] val[{3:x02}]", chipId, dat.port, (int)dat.address, (int)dat.data)); mds.WriteYM2610((byte)chipId, (byte)dat.port, (byte)dat.address, (byte)dat.data); }
private static void OPMWrite(int chipId, ChipDatum dat) { if (dat != null && dat.addtionalData != null) { MmlDatum md = (MmlDatum)dat.addtionalData; if (md.linePos != null) { //Log.WriteLine(LogLevel.TRACE, string.Format("! OPM i{0} r{1} c{2}" // , chipId // , md.linePos.row // , md.linePos.col // )); } } if (dat.address == -1) { return; } //if (dat.address == 0x27)// && d <= 0x1d) //{ // Log.WriteLine(LogLevel.TRACE, string.Format("Out ChipOPM:{0} Port:{1} Adr:[{2:x02}] val[{3:x02}]", chipId, dat.port, (int)dat.address, (int)dat.data)); //} switch (device) { case 0: mds.WriteYM2151((byte)chipId, (byte)dat.address, (byte)dat.data); break; case 1: case 2: rsc.setRegister(dat.address, dat.data); break; } }
private int SaveMusicExtendFormat(int length, int option) { dat.Clear(); //固定長ヘッダー情報 作成 dat.Add(new MmlDatum(0x6d)); // m dat.Add(new MmlDatum(0x75)); // u dat.Add(new MmlDatum(0x50)); // P dat.Add(new MmlDatum(0x62)); // b dat.Add(new MmlDatum(0x30)); // 0 dat.Add(new MmlDatum(0x31)); // 1 dat.Add(new MmlDatum(0x30)); // 0 dat.Add(new MmlDatum(0x30)); // 0 dat.Add(new MmlDatum(0x05)); // 可変長ヘッダー情報の数。 dat.Add(new MmlDatum(work.MAXChips)); // 使用する音源の数(0~) dat.Add(new MmlDatum(work.MAXCH * work.MAXChips)); // 使用するパートの総数(0~) dat.Add(new MmlDatum(0x00)); int n = 0; for (int i = 0; i < work.MAXChips; i++) { for (int j = 0; j < work.MAXCH; j++) { for (int k = 0; k < work.MAXPG; k++) { if (work.bufCount[i][j][k] > 1) { n++; } } } } dat.Add(new MmlDatum(n));// 使用するページの総数(0~) dat.Add(new MmlDatum(0x00)); int instSets = 0; for (int i = 0; i < work.MAXChips; i++) { instSets += work.OTONUM[i]; } dat.Add(new MmlDatum(instSets > 0 ? 1 : 0));// 使用するInstrumentセットの総数(0~) dat.Add(new MmlDatum(0x00)); bool pcmuse = ((option & 2) == 0); int[] pcmsize = new int[6]; int m = 0; for (int k = 0; k < 6; k++) { pcmsize[k] = (pcmdata[k] == null) ? 0 : pcmdata[k].Length; pcmdata[k] = (!pcmuse ? null : pcmdata[k]); pcmsize[k] = (!pcmuse ? 0 : pcmsize[k]); if (pcmdata[k] == null || pcmsize[k] == 0) { pcmdata[k] = null; pcmsize[k] = 0; m++; } } if (m == 6) { pcmuse = false; } dat.Add(new MmlDatum(pcmuse ? 6 : 0));// 使用するPCMセットの総数(0~) dat.Add(new MmlDatum(0x00)); dat.Add(new MmlDatum(0x00)); // 曲情報への絶対アドレス dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // 曲情報のサイズ dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum((byte)work.JCLOCK)); // JCLOCKの値(Jコマンドのタグ位置) dat.Add(new MmlDatum((byte)(work.JCLOCK >> 8))); dat.Add(new MmlDatum((byte)(work.JCLOCK >> 16))); dat.Add(new MmlDatum((byte)(work.JCLOCK >> 24))); dat.Add(new MmlDatum((byte)work.JPLINE));//jump line number dat.Add(new MmlDatum((byte)(work.JPLINE >> 8))); dat.Add(new MmlDatum((byte)(work.JPLINE >> 16))); dat.Add(new MmlDatum((byte)(work.JPLINE >> 24))); work.compilerInfo.jumpRow = -1; work.compilerInfo.jumpCol = -1; if (work.JPLINE >= 0) { Log.WriteLine(LogLevel.INFO, string.Format("#Jump count [{0}]. channelNumber[{1}]", work.JCLOCK, work.JCHCOM[0])); Log.WriteLine(LogLevel.INFO, string.Format("#Jump line [row:{0} col:{1}].", work.JPLINE, work.JPCOL)); work.compilerInfo.jumpRow = work.JPLINE; work.compilerInfo.jumpCol = work.JPCOL; } //可変長ヘッダー情報 //Chip Define division. int pcmI = 0; for (int chipI = 0; chipI < work.MAXChips; chipI++) { dat.Add(new MmlDatum((byte)(chipI >> 0))); // Chip Index dat.Add(new MmlDatum((byte)(chipI >> 8))); // int opmIdentifyNumber = 0x0000_0030; int opnaIdentifyNumber = 0x0000_0048; int opnbIdentifyNumber = 0x0000_004c; int opmMasterClock = 3579545; int opnaMasterClock = 7987200; int opnbMasterClock = 8000000; if (chipI < 2) { dat.Add(new MmlDatum((byte)(opnaIdentifyNumber >> 0))); // Chip Identify number dat.Add(new MmlDatum((byte)(opnaIdentifyNumber >> 8))); // dat.Add(new MmlDatum((byte)(opnaIdentifyNumber >> 16))); // dat.Add(new MmlDatum((byte)(opnaIdentifyNumber >> 24))); // dat.Add(new MmlDatum((byte)opnaMasterClock)); // Chip Clock dat.Add(new MmlDatum((byte)(opnaMasterClock >> 8))); dat.Add(new MmlDatum((byte)(opnaMasterClock >> 16))); dat.Add(new MmlDatum((byte)(opnaMasterClock >> 24))); } else if (chipI < 4) { dat.Add(new MmlDatum((byte)(opnbIdentifyNumber >> 0))); // Chip Identify number dat.Add(new MmlDatum((byte)(opnbIdentifyNumber >> 8))); // dat.Add(new MmlDatum((byte)(opnbIdentifyNumber >> 16))); // dat.Add(new MmlDatum((byte)(opnbIdentifyNumber >> 24))); // dat.Add(new MmlDatum((byte)opnbMasterClock)); // Chip Clock dat.Add(new MmlDatum((byte)(opnbMasterClock >> 8))); dat.Add(new MmlDatum((byte)(opnbMasterClock >> 16))); dat.Add(new MmlDatum((byte)(opnbMasterClock >> 24))); } else { dat.Add(new MmlDatum((byte)(opmIdentifyNumber >> 0))); // Chip Identify number dat.Add(new MmlDatum((byte)(opmIdentifyNumber >> 8))); // dat.Add(new MmlDatum((byte)(opmIdentifyNumber >> 16))); // dat.Add(new MmlDatum((byte)(opmIdentifyNumber >> 24))); // dat.Add(new MmlDatum((byte)opmMasterClock)); // Chip Clock dat.Add(new MmlDatum((byte)(opmMasterClock >> 8))); dat.Add(new MmlDatum((byte)(opmMasterClock >> 16))); dat.Add(new MmlDatum((byte)(opmMasterClock >> 24))); } dat.Add(new MmlDatum(0x00)); // Chip Option dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x01)); // Heart Beat (1:OPNA Timer) dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // Heart Beat2 (0:Unuse) dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(0x00)); // dat.Add(new MmlDatum(work.MAXCH)); //part count n = work.OTONUM[chipI] > 0 ? 1 : 0; dat.Add(new MmlDatum(n));// 使用するInstrumentセットの総数(0~) for (int i = 0; i < n; i++) { dat.Add(new MmlDatum(0x00));// この音源Chipで使用するInstrumentセットの番号。上記パラメータの個数だけ繰り返す。 dat.Add(new MmlDatum(0x00)); } n = pcmuse ? (chipI < 2 ? 1 : (chipI < 4 ? 2 : 0)) : 0; dat.Add(new MmlDatum(n));// この音源Chipで使用するPCMセットの個数 for (int i = 0; i < n; i++) { dat.Add(new MmlDatum((byte)pcmI));// この音源Chipで使用するPCMセットの番号。上記パラメータの個数だけ繰り返す。 dat.Add(new MmlDatum((byte)(pcmI >> 8))); pcmI++; } } //Part division. for (int i = 0; i < work.MAXChips; i++) { for (int j = 0; j < work.MAXCH; j++) { n = 0; for (int pg = 0; pg < work.MAXPG; pg++) { if (work.bufCount[i][j][pg] > 1) { n++; } } dat.Add(new MmlDatum(n));//ページの数(0~) } } //Page division. for (int i = 0; i < work.MAXChips; i++) { for (int j = 0; j < work.MAXCH; j++) { for (int pg = 0; pg < work.MAXPG; pg++) { if (work.bufCount[i][j][pg] < 2) { continue; } n = work.bufCount[i][j][pg]; dat.Add(new MmlDatum((byte)n));// ページの大きさ(0~) dat.Add(new MmlDatum((byte)(n >> 8))); dat.Add(new MmlDatum((byte)(n >> 16))); dat.Add(new MmlDatum((byte)(n >> 24))); n = work.loopPoint[i][j][pg]; dat.Add(new MmlDatum((byte)n));// ページのループポイント(0~) dat.Add(new MmlDatum((byte)(n >> 8))); dat.Add(new MmlDatum((byte)(n >> 16))); dat.Add(new MmlDatum((byte)(n >> 24))); } } } //Instrument set division. n = instSets > 0 ? 1 : 0;// 使用するInstrumentセットの総数(0~) if (n > 0) { dat.Add(new MmlDatum((byte)mucInfo.bufUseVoice.Count)); dat.Add(new MmlDatum((byte)(mucInfo.bufUseVoice.Count >> 8))); dat.Add(new MmlDatum((byte)(mucInfo.bufUseVoice.Count >> 16))); dat.Add(new MmlDatum((byte)(mucInfo.bufUseVoice.Count >> 24))); } //PCM set division. if (pcmuse) { for (int i = 0; i < pcmI; i++) { dat.Add(new MmlDatum((byte)pcmsize[i])); dat.Add(new MmlDatum((byte)(pcmsize[i] >> 8))); dat.Add(new MmlDatum((byte)(pcmsize[i] >> 16))); dat.Add(new MmlDatum((byte)(pcmsize[i] >> 24))); } } //ページデータ出力 for (int i = 0; i < work.MAXChips; i++) { for (int j = 0; j < work.MAXCH; j++) { for (int pg = 0; pg < work.MAXPG; pg++) { if (work.bufCount[i][j][pg] < 2) { continue; } for (int p = 0; p < work.bufCount[i][j][pg]; p++) { dat.Add(mucInfo.bufPage[i][j][pg].Get(p)); } } } } //Instrumentデータ出力 if (instSets > 0) { for (int i = 0; i < mucInfo.bufUseVoice.Count; i++) { dat.Add(mucInfo.bufUseVoice.Get(i)); } } //PCMデータ出力 if (pcmuse) { for (int i = 0; i < pcmI; i++) { for (int j = 0; j < pcmsize[i]; j++) { dat.Add(new MmlDatum(pcmdata[i][j])); } } } //曲情報出力 int infoAdr = dat.Count; dat[0x12] = new MmlDatum((byte)infoAdr); dat[0x13] = new MmlDatum((byte)(infoAdr >> 8)); dat[0x14] = new MmlDatum((byte)(infoAdr >> 16)); dat[0x15] = new MmlDatum((byte)(infoAdr >> 24)); bool useDriverTAG = false; if (tags != null) { foreach (Tuple <string, string> tag in tags) { if (tag.Item1 == "driver") { useDriverTAG = true; } } } if (!useDriverTAG && mucInfo.DriverType == MUCInfo.enmDriverType.DotNet) { if (tags == null) { tags = new List <Tuple <string, string> >(); } tags.Add(new Tuple <string, string>("driver", MUCInfo.DotNET)); } if (tags != null) { int tagsize = 0; foreach (Tuple <string, string> tag in tags) { if (tag.Item1 != null && tag.Item1.Length > 0 && tag.Item1[0] == '*') { continue; } byte[] b = enc.GetSjisArrayFromString(string.Format("#{0} {1}\r\n", tag.Item1, tag.Item2)); tagsize += b.Length; foreach (byte bd in b) { dat.Add(new MmlDatum(bd)); } } dat[0x16] = new MmlDatum((byte)tagsize); dat[0x17] = new MmlDatum((byte)(tagsize >> 8)); dat[0x18] = new MmlDatum((byte)(tagsize >> 16)); dat[0x19] = new MmlDatum((byte)(tagsize >> 24)); } return(0); }
//private int SaveMusic(string fname, ushort start, ushort length, int option) private int SaveMusic(int length, int option, bool isExtendFormat) { // 音楽データファイルを出力(コンパイルが必要) // option : 1 = #タグによるvoice設定を無視 // 2 = PCM埋め込みをスキップ // (戻り値が0以外の場合はエラー) // usePageFunc : ページ機能を使用しているか // if (isExtendFormat) { return(SaveMusicExtendFormat(length, option)); } int footsize; footsize = 1;//かならず1以上 int pcmsize = (pcmdata[0] == null) ? 0 : pcmdata[0].Length; bool pcmuse = ((option & 2) == 0); pcmdata[0] = (!pcmuse ? null : pcmdata[0]); int pcmptr = (!pcmuse ? 0 : (32 + length + footsize)); pcmsize = (!pcmuse ? 0 : pcmsize); if (pcmuse) { if (pcmdata[0] == null || pcmsize == 0) { pcmuse = false; pcmdata[0] = null; pcmptr = 0; pcmsize = 0; } } int dataOffset = 0x50; int dataSize = length; int tagOffset = length + 0x50; dat.Clear(); dat.Add(new MmlDatum(0x4d)); // M dat.Add(new MmlDatum(0x55)); // U dat.Add(new MmlDatum(0x42)); // B dat.Add(new MmlDatum(0x38)); // 8 dat.Add(new MmlDatum((byte)dataOffset)); dat.Add(new MmlDatum((byte)(dataOffset >> 8))); dat.Add(new MmlDatum((byte)(dataOffset >> 16))); dat.Add(new MmlDatum((byte)(dataOffset >> 24))); dat.Add(new MmlDatum((byte)dataSize)); dat.Add(new MmlDatum((byte)(dataSize >> 8))); dat.Add(new MmlDatum((byte)(dataSize >> 16))); dat.Add(new MmlDatum((byte)(dataSize >> 24))); dat.Add(new MmlDatum((byte)tagOffset)); dat.Add(new MmlDatum((byte)(tagOffset >> 8))); dat.Add(new MmlDatum((byte)(tagOffset >> 16))); dat.Add(new MmlDatum((byte)(tagOffset >> 24))); dat.Add(new MmlDatum(0));//tagdata size(dummy) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum((byte)pcmptr));//pcmdata ptr(32bit) dat.Add(new MmlDatum((byte)(pcmptr >> 8))); dat.Add(new MmlDatum((byte)(pcmptr >> 16))); dat.Add(new MmlDatum((byte)(pcmptr >> 24))); dat.Add(new MmlDatum((byte)pcmsize));//pcmdata size(32bit) dat.Add(new MmlDatum((byte)(pcmsize >> 8))); dat.Add(new MmlDatum((byte)(pcmsize >> 16))); dat.Add(new MmlDatum((byte)(pcmsize >> 24))); dat.Add(new MmlDatum((byte)work.JCLOCK));// JCLOCKの値(Jコマンドのタグ位置) dat.Add(new MmlDatum((byte)(work.JCLOCK >> 8))); dat.Add(new MmlDatum((byte)work.JPLINE));//jump line number dat.Add(new MmlDatum((byte)(work.JPLINE >> 8))); dat.Add(new MmlDatum(0));//ext_flags(?) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(1)); //ext_system(?) dat.Add(new MmlDatum(2)); //ext_target(?) dat.Add(new MmlDatum(11)); //ext_channel_num dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum((byte)work.OTONUM[0]));//ext_fmvoice_num dat.Add(new MmlDatum((byte)(work.OTONUM[0] >> 8))); dat.Add(new MmlDatum(0));//ext_player(?) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0));//pad1 dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); for (int i = 0; i < 32; i++) { dat.Add(new MmlDatum((byte)mucInfo.bufDefVoice.Get(i))); } work.compilerInfo.jumpRow = -1; work.compilerInfo.jumpCol = -1; if (work.JPLINE >= 0) { Log.WriteLine(LogLevel.INFO, string.Format("#Jump count [{0}]. channelNumber[{1}]", work.JCLOCK, work.JCHCOM[0])); Log.WriteLine(LogLevel.INFO, string.Format("#Jump line [row:{0} col:{1}].", work.JPLINE, work.JPCOL)); work.compilerInfo.jumpRow = work.JPLINE; work.compilerInfo.jumpCol = work.JPCOL; } for (int i = 0; i < length; i++) { dat.Add(mucInfo.bufDst.Get(i)); } dat[dataOffset + 0] = new MmlDatum(0);//バイナリに含まれる曲データ数-1 dat[dataOffset + 1] = new MmlDatum((byte)work.OTODAT); dat[dataOffset + 2] = new MmlDatum((byte)(work.OTODAT >> 8)); dat[dataOffset + 3] = new MmlDatum((byte)work.ENDADR); dat[dataOffset + 4] = new MmlDatum((byte)(work.ENDADR >> 8)); if (dat[dataOffset + 5] == null) { dat[dataOffset + 5] = new MmlDatum(0);//テンポコマンド(タイマーB)を未設定時nullのままになってしまうので、とりあえず値をセット } footsize = 0; bool useDriverTAG = false; if (tags != null) { foreach (Tuple <string, string> tag in tags) { if (tag.Item1 == "driver") { useDriverTAG = true; } } } //データサイズが64k超えていたらdotnet確定 if (work.ENDADR - work.MU_NUM > 0xffff) { if (mucInfo.DriverType != MUCInfo.enmDriverType.DotNet) { //TBD return(1); } } if (!useDriverTAG && mucInfo.DriverType == MUCInfo.enmDriverType.DotNet) { if (tags == null) { tags = new List <Tuple <string, string> >(); } tags.Add(new Tuple <string, string>("driver", MUCInfo.DotNET)); } if (tags != null) { foreach (Tuple <string, string> tag in tags) { if (tag.Item1 != null && tag.Item1.Length > 0 && tag.Item1[0] == '*') { continue; } if (string.IsNullOrEmpty(tag.Item1) && !string.IsNullOrEmpty(tag.Item2) && tag.Item2.Trim()[0] == '*') { continue; } byte[] b = enc.GetSjisArrayFromString(string.Format("#{0} {1}\r\n", tag.Item1, tag.Item2)); footsize += b.Length; foreach (byte bd in b) { dat.Add(new MmlDatum(bd)); } } } if (footsize > 0) { dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); footsize += 4; dat[16] = new MmlDatum((byte)footsize);//tagdata size(32bit) dat[17] = new MmlDatum((byte)(footsize >> 8)); dat[18] = new MmlDatum((byte)(footsize >> 16)); dat[19] = new MmlDatum((byte)(footsize >> 24)); } else { tags = null; } if (tags == null) { //クリア for (int i = 0; i < 8; i++) { dat[12 + i] = new MmlDatum(0); } } if (pcmuse) { for (int i = 0; i < pcmsize; i++) { dat.Add(new MmlDatum(pcmdata[0][i])); } if (pcmsize > 0) { pcmptr = 16 * 3 + 32 + length + footsize; dat[20] = new MmlDatum((byte)pcmptr);//pcmdata size(32bit) dat[21] = new MmlDatum((byte)(pcmptr >> 8)); dat[22] = new MmlDatum((byte)(pcmptr >> 16)); dat[23] = new MmlDatum((byte)(pcmptr >> 24)); } } return(0); }
//private int SaveMusic(string fname, ushort start, ushort length, int option) private int SaveMusic(int length, int option) { // 音楽データファイルを出力(コンパイルが必要) // option : 1 = #タグによるvoice設定を無視 // 2 = PCM埋め込みをスキップ // (戻り値が0以外の場合はエラー) // int footsize; footsize = 1;//かならず1以上 int pcmsize = (pcmdata == null) ? 0 : pcmdata.Length; bool pcmuse = ((option & 2) == 0); pcmdata = (!pcmuse ? null : pcmdata); int pcmptr = (!pcmuse ? 0 : (32 + length + footsize)); pcmsize = (!pcmuse ? 0 : pcmsize); if (pcmuse) { if (pcmdata == null || pcmsize == 0) { pcmuse = false; pcmdata = null; pcmptr = 0; pcmsize = 0; } } int dataOffset = 0x50; int dataSize = length; int tagOffset = length + 0x50; dat.Clear(); dat.Add(new MmlDatum(0x4d)); // M dat.Add(new MmlDatum(0x55)); // U dat.Add(new MmlDatum(0x42)); // B dat.Add(new MmlDatum(0x38)); // 8 dat.Add(new MmlDatum((byte)dataOffset)); dat.Add(new MmlDatum((byte)(dataOffset >> 8))); dat.Add(new MmlDatum((byte)(dataOffset >> 16))); dat.Add(new MmlDatum((byte)(dataOffset >> 24))); dat.Add(new MmlDatum((byte)dataSize)); dat.Add(new MmlDatum((byte)(dataSize >> 8))); dat.Add(new MmlDatum((byte)(dataSize >> 16))); dat.Add(new MmlDatum((byte)(dataSize >> 24))); dat.Add(new MmlDatum((byte)tagOffset)); dat.Add(new MmlDatum((byte)(tagOffset >> 8))); dat.Add(new MmlDatum((byte)(tagOffset >> 16))); dat.Add(new MmlDatum((byte)(tagOffset >> 24))); dat.Add(new MmlDatum(0));//tagdata size(dummy) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum((byte)pcmptr));//pcmdata ptr(32bit) dat.Add(new MmlDatum((byte)(pcmptr >> 8))); dat.Add(new MmlDatum((byte)(pcmptr >> 16))); dat.Add(new MmlDatum((byte)(pcmptr >> 24))); dat.Add(new MmlDatum((byte)pcmsize));//pcmdata size(32bit) dat.Add(new MmlDatum((byte)(pcmsize >> 8))); dat.Add(new MmlDatum((byte)(pcmsize >> 16))); dat.Add(new MmlDatum((byte)(pcmsize >> 24))); dat.Add(new MmlDatum((byte)work.JCLOCK));// JCLOCKの値(Jコマンドのタグ位置) dat.Add(new MmlDatum((byte)(work.JCLOCK >> 8))); dat.Add(new MmlDatum((byte)work.JPLINE));//jump line number dat.Add(new MmlDatum((byte)(work.JPLINE >> 8))); dat.Add(new MmlDatum(0));//ext_flags(?) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(1)); //ext_system(?) dat.Add(new MmlDatum(2)); //ext_target(?) dat.Add(new MmlDatum(11)); //ext_channel_num dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum((byte)work.OTONUM));//ext_fmvoice_num dat.Add(new MmlDatum((byte)(work.OTONUM >> 8))); dat.Add(new MmlDatum(0));//ext_player(?) dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0));//pad1 dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); for (int i = 0; i < 32; i++) { dat.Add(new MmlDatum((byte)mucInfo.bufDefVoice.Get(i))); } if (work.JPLINE >= 0) { Log.WriteLine(LogLevel.INFO, string.Format("#Jump count [{0}]. channelNumber[{1}]", work.JCLOCK, work.JCHCOM[0])); Log.WriteLine(LogLevel.INFO, string.Format("#Jump line [row:{0} col:{1}].", work.JPLINE, work.JPCOL)); } for (int i = 0; i < length; i++) { dat.Add(mucInfo.bufDst.Get(i)); } dat[dataOffset + 0] = new MmlDatum(0);//バイナリに含まれる曲データ数-1 dat[dataOffset + 1] = new MmlDatum((byte)work.OTODAT); dat[dataOffset + 2] = new MmlDatum((byte)(work.OTODAT >> 8)); dat[dataOffset + 3] = new MmlDatum((byte)work.ENDADR); dat[dataOffset + 4] = new MmlDatum((byte)(work.ENDADR >> 8)); //dat[dataOffset + 5] = 0xff; //たぶん テンポコマンド(タイマーB)設定時に更新される footsize = 0; bool useDriverTAG = false; if (tags != null) { foreach (Tuple <string, string> tag in tags) { if (tag.Item1 == "driver") { useDriverTAG = true; } } } //データサイズが64k超えていたらdotnet確定 if (work.ENDADR - work.MU_NUM > 0xffff) { mucInfo.isDotNET = true; } if (!useDriverTAG && mucInfo.isDotNET) { if (tags == null) { tags = new List <Tuple <string, string> >(); } tags.Add(new Tuple <string, string>("driver", MUCInfo.DotNET)); } if (tags != null) { foreach (Tuple <string, string> tag in tags) { byte[] b = enc.GetSjisArrayFromString(string.Format("#{0} {1}\r\n", tag.Item1, tag.Item2)); footsize += b.Length; foreach (byte bd in b) { dat.Add(new MmlDatum(bd)); } } } if (footsize > 0) { dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); dat.Add(new MmlDatum(0)); footsize += 4; dat[16] = new MmlDatum((byte)footsize);//tagdata size(32bit) dat[17] = new MmlDatum((byte)(footsize >> 8)); dat[18] = new MmlDatum((byte)(footsize >> 16)); dat[19] = new MmlDatum((byte)(footsize >> 24)); } else { tags = null; } if (tags == null) { //クリア for (int i = 0; i < 8; i++) { dat[12 + i] = new MmlDatum(0); } } if (pcmuse) { for (int i = 0; i < pcmsize; i++) { dat.Add(new MmlDatum(pcmdata[i])); } if (pcmsize > 0) { pcmptr = 16 * 3 + 32 + length + footsize; dat[20] = new MmlDatum((byte)pcmptr);//pcmdata size(32bit) dat[21] = new MmlDatum((byte)(pcmptr >> 8)); dat[22] = new MmlDatum((byte)(pcmptr >> 16)); dat[23] = new MmlDatum((byte)(pcmptr >> 24)); } } return(0); }