public byte[] WriteMidi(MUS mus, string name) { queuedtime = 0; tracksize = 0; channel_map = new int[NUM_CHANNELS]; midi = new List <byte>(); DoMus2mid(mus); return(midi.ToArray()); }
IEnumerator CreateMap() { //destroy all children of map parent for (int i = 0; i < mapParent.childCount; i++) { GameObject.Destroy(mapParent.GetChild(i).gameObject); } yield return(new WaitForEndOfFrame()); //use this if you want to select one map in particular //if (mapSelected == 1) { mapSelected = 23; } openedMap = reader.newWad.maps[mapSelected - 1]; //use this if you want to pick a selection of maps to choose from instead of going through the whole list //int[] mapMapper = { 3, 20, 26, 28, 30, 35 }; //openedMap = reader.newWad.maps[mapMapper[(mapSelected - 1) % mapMapper.Length] - 1]; //display map Debug.Log("MAP: " + mapSelected); //read and play music MUS mus = reader.ReadMusEntry(mapSelected - 1); midiplayer.PlayMusic(musmid.WriteMidi(mus, mus.name)); //fill in any missing map information fillInfo(openedMap); float minx = 0; float miny = 0; foreach (Vector3 vert in openedMap.vertexes) { if (vert.x > minx) { minx = vert.x; } if (vert.z > miny) { miny = vert.z; } } skybox.transform.position = new Vector3(minx, 0, miny); //add sectors and monsters to map AddSectors(); SetSkyboxTexture(); AddThings(); skyboxScript.ChangeSky(); }
public MUS ReadMusEntry(int songNumber) { List <DrctEntry> musList = new List <DrctEntry>(); foreach (DrctEntry entry in newWad.directory) //find all the mus's in the wad { if (entry.name.StartsWith("D_")) { musList.Add(entry); } } DrctEntry mus = musList[songNumber]; //which song are we listening to today byte[] musBytes = new byte[mus.size]; wadOpener.Position = mus.filepos; wadOpener.Read(musBytes, 0, musBytes.Length); MUS newMUS = new MUS(); byte[] channelVolume = new byte[16]; newMUS.name = mus.name; //read the header of the mus file newMUS.id = new String(System.Text.Encoding.ASCII.GetChars(musBytes, 0, 3)); newMUS.scoreLen = BitConverter.ToUInt16(musBytes, 4); newMUS.scoreStart = BitConverter.ToUInt16(musBytes, 6); newMUS.channels = BitConverter.ToUInt16(musBytes, 8); newMUS.sec_channels = BitConverter.ToUInt16(musBytes, 10); newMUS.instrCnt = BitConverter.ToUInt16(musBytes, 12); newMUS.dummy = BitConverter.ToUInt16(musBytes, 14); List <int> instrList = new List <int>();//temporary list for storing instruments for (int j = 16; j < newMUS.scoreStart; j += 2) { instrList.Add(BitConverter.ToUInt16(musBytes, j)); //get the instrument } newMUS.instruments = instrList.ToArray(); //store the temporary list to the newMUS list int i = newMUS.scoreStart; while (i < musBytes.Length) { //read the 'score' Mus_Event newEvent = new Mus_Event(); newEvent.channelNum = (byte)(musBytes[i] & 0x0F); newEvent.musEventType = (byte)((musBytes[i] & 0x70) >> 4); newEvent.last = (((musBytes[i] & 0x80) >> 7) == 1); i++; //finished reading the descriptor byte if (newEvent.musEventType == 0) //Release Note { newEvent.note = (byte)(musBytes[i] & 0x7F); i++; //finished reading the released note byte } else if (newEvent.musEventType == 1) //Play Note { bool volBit = ((musBytes[i] & 0x80) >> 7) == 1; newEvent.note = (byte)(musBytes[i] & 0x7F); i++; //finished reading the note byte if (volBit) //if the last bit of the first byte is set, get the new vol from the 2nd byte { newEvent.vol = (byte)(musBytes[i] & 0x7F); channelVolume[newEvent.channelNum] = newEvent.vol; i++; //finished reading the vol byte } else //otherwise use the volume of the previous note on the channel is used. { newEvent.vol = channelVolume[newEvent.channelNum]; } } else if (newEvent.musEventType == 2)//Pitch Wheel { newEvent.pitch = (byte)(musBytes[i]); i++; //finished reading pitch wheel byte } else if (newEvent.musEventType == 3) //System Event { newEvent.sysEventNum = (byte)(musBytes[i] & 0x7F); i++; //finished reading sys event byte } else if (newEvent.musEventType == 4) //Change Controller { newEvent.contNum = (byte)(musBytes[i] & 0x7F); i++; //finished reading controller number byte newEvent.contVal = (byte)(musBytes[i] & 0x7F); i++; //finished reading controller value byte } else if (newEvent.musEventType == 5 || newEvent.musEventType == 7) { i++; //???????extra byte?????????? } else if (newEvent.musEventType == 6) //Score end (end of mus) { //END OF FILE EVENT newEvent.scoreEnd = true; //set the events scoreEnd bool to true newEvent.time = newMUS.musEvents[newMUS.musEvents.Count - 1].time; // set the end time to the last event's for some reason? newMUS.musEvents.Add(newEvent); //save the event newWad.music.Add(newMUS); //save the MUS break; } if (newEvent.last) //delay { int delay = 0; bool moreDelay = true; //if there is another delay byte after the current byte while (moreDelay) { moreDelay = (((BitConverter.ToChar(musBytes, i) & 0x80) >> 7) == 1); //set moreDelay by checking the LAST bit of the CURRENT BYTE byte newByte = musBytes[i]; delay = delay * 128 + (newByte & 0x7F); //set the delay i++; //next byte } newEvent.time = delay;//set the new time info } newMUS.musEvents.Add(newEvent);//save the event information } return(newMUS); //newWad.music.Add(newMUS); }
// Read a MUS file from a MemChunk (musinput) and output a MIDI file to // a MemChunk (midioutput). // // Returns true if successful, false otherwise public static bool DoMus2mid(MUS mus) { int channel; // Channel number // Buffer used for MIDI track size record byte[] tracksizebuffer = new byte[4]; // Flag for when the score end marker is hit. bool hitscoreend = false; // Used in building up time delays int timedelay; // Initialise channel map to mark all channels as unused. for (channel = 0; channel < NUM_CHANNELS; channel++) { channel_map[channel] = -1; } // Check MUS header if (mus.id != "MUS") { return(false); } // So, we can assume the MUS file is faintly legit. Let's start writing MIDI data... midi.AddRange(midiheader); //write the midi header tracksize = 0; // Now, process the MUS file: while (!hitscoreend) { // Handle a block of events: timedelay = 0; foreach (Mus_Event mEvent in mus.musEvents) { // Fetch channel number and event code: //channel = mEvent.channelNum; channel = GetMIDIChannel(mEvent.channelNum); switch (mEvent.musEventType) { case 0: WriteReleaseKey((byte)channel, mEvent.note); break; case 1: if (mEvent.vol != 0) { channelvelocities[channel] = mEvent.vol; } WritePressKey((byte)channel, mEvent.note, (byte)channelvelocities[channel]); break; case 2: WritePitchWheel((byte)channel, mEvent.pitch * 64); break; case 3: if (mEvent.contNum < 10 || mEvent.contNum > 14) { continue; } WriteChangeController_Valueless((byte)channel, (byte)controller_map[mEvent.contNum]); break; case 4: if (mEvent.contNum == 0) { WriteChangePatch((byte)channel, mEvent.contVal); } else { if (mEvent.contNum < 1 || mEvent.contNum > 9) { continue; } WriteChangeController_Valued((byte)channel, (byte)controller_map[mEvent.contNum], mEvent.contVal); } break; case 6: hitscoreend = true; break; default: continue; } queuedtime = mEvent.time; } } // End of track if (!WriteEndTrack()) { return(false); } // Write the track size into the stream midi[MIDI_TRACKLENGTH_OFS + 0] = (byte)((tracksize >> 24) & 0xff); midi[MIDI_TRACKLENGTH_OFS + 1] = (byte)((tracksize >> 16) & 0xff); midi[MIDI_TRACKLENGTH_OFS + 2] = (byte)((tracksize >> 8) & 0xff); midi[MIDI_TRACKLENGTH_OFS + 3] = (byte)(tracksize & 0xff); //midi.AddRange(tracksizebuffer); return(true); }