/// <summary> /// Write velocity region. /// </summary> /// <param name="bw">The writer.</param> /// <param name="r">Velocity region to write.</param> public void WriteVelocityInfo(BinaryDataWriter bw, VelocityRegion r) { //Write wave index. bw.Write((uint)r.WaveIndex); //Flags are always written the same, so. bw.Write((uint)0x21F); //Original note. bw.Write((uint)r.OriginalKey); //Volume. bw.Write((uint)r.Volume); //Pan. bw.Write((uint)(r.Pan + (r.SurroundPan << 8))); //Pitch. bw.Write(r.Pitch); //Note info. bw.Write((uint)((r.PercussionMode ? 1 : 0) + (r.KeyGroup << 8) + ((byte)r.InterPolationType << 16))); //ADSHR. bw.Write((UInt32)0x20); bw.Write((UInt32)0); bw.Write((UInt32)8); bw.Write(r.Attack); bw.Write(r.Decay); bw.Write(r.Sustain); bw.Write(r.Hold); bw.Write(r.Release); bw.Write(new byte[3]); }
/// <summary> /// Get file name of wave to use. /// </summary> /// <param name="v"></param> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static string GetWaveFileName(VelocityRegion v, SoundArchive a, BankEntry b) { //Base path. string path = "../Wave Archives"; //Get entry. var e = (b.File.File as SoundBank).Waves[v.WaveIndex]; //Get folder name. path += "/" + Path.GetFileNameWithoutExtension(a.WaveArchives[e.WarIndex].File.FileName); //Get file name. path += "/" + e.WaveIndex + ".wav"; //Return the path. return(path); }
/// <summary> /// Write a velocity region. /// </summary> /// <param name="v">Velocity region.</param> /// <param name="a">Sound archive.</param> /// <param name="b">Bank entry.</param> /// <param name="start">Starting note.</param> /// <param name="end">Ending note.</param> /// <param name="x">The writer.</param> public static void WriteVelocityRegion(VelocityRegion v, SoundArchive a, BankEntry b, int start, int end, XmlTextWriter x) { //Velocity region. x.WriteStartElement("VelocityRegion"); //Parameters. StartUselessParameters(x); x.WriteElementString("FilePath", GetWaveFileName(v, a, b)); x.WriteElementString("WaveEncoding", "Adpcm"); x.WriteElementString("OriginalKey", v.OriginalKey + ""); x.WriteStartElement("Envelope"); x.WriteStartElement("Parameters"); x.WriteElementString("Attack", v.Attack + ""); x.WriteElementString("Decay", v.Decay + ""); x.WriteElementString("Sustain", v.Sustain + ""); x.WriteElementString("Hold", v.Hold + ""); x.WriteElementString("Release", v.Release + ""); x.WriteEndElement(); //Parameters. x.WriteEndElement(); //Envelope. x.WriteElementString("VelocityMin", start + ""); x.WriteElementString("VelocityMax", end + ""); x.WriteElementString("Volume", v.Volume + ""); x.WriteElementString("Pan", v.Pan + ""); Pitch pitch = new Pitch(v.Pitch); x.WriteElementString("PitchSemitones", pitch.Semitones + ""); x.WriteElementString("PitchCents", pitch.Cents + ""); x.WriteElementString("KeyGroup", v.KeyGroup + ""); switch (v.InterPolationType) { case VelocityRegion.EInterPolationType.PolyPhase: x.WriteElementString("InterpolationType", "Polyphase"); break; case VelocityRegion.EInterPolationType.Linear: x.WriteElementString("InterpolationType", "Linear"); break; } x.WriteElementString("InstrumentNoteOffMode", v.PercussionMode ? "Ignore" : "Release"); //End parameters. EndUselessParameters(x); //End velocity region. x.WriteEndElement(); }
/// <summary> /// Create a new Velocity region range. /// </summary> /// <param name="startNote">Starting note.</param> /// <param name="endVelocity">Ending note.</param> /// <param name="keyRegion">Velocity region.</param> public VelocityRegionRange(sbyte startVelocity, sbyte endVelocity, VelocityRegion velocityRegion) { StartVelocity = startVelocity; EndVelocity = endVelocity; VelocityRegion = velocityRegion; }
/// <summary> /// Read a velocity region. /// </summary> /// <param name="br">The reader.</param> /// <returns>The velocity region.</returns> public VelocityRegion ReadVelocityInfo(BinaryDataReader br, FileReader FileReader) { //Start structure. FileReader.StartStructure(br); //New velocity region. VelocityRegion r = new VelocityRegion(); //First is the wave id index. r.WaveIndex = (int)br.ReadUInt32(); //Flags. FlagParameters f = new FlagParameters(ref br); //Original key. 0x000000KK. r.OriginalKey = (sbyte)(0xFF & SoundArchiveReader.GetFlagValue(f, 0, 60)); //Volume. 0x000000VV. r.Volume = (byte)(0xFF & SoundArchiveReader.GetFlagValue(f, 1, 127)); //Pan. 0x0000SSPP. S = Span, P = Pan. r.Pan = (sbyte)(0xFF & SoundArchiveReader.GetFlagValue(f, 2, 64)); r.SurroundPan = (sbyte)((0xFF00 & SoundArchiveReader.GetFlagValue(f, 2)) >> 8); //Pitch. r.Pitch = BitConverter.ToSingle(BitConverter.GetBytes(SoundArchiveReader.GetFlagValue(f, 3, 0x3F800000)), 0); //Note parameters. 0x00TTGGII. T = Interpolation Type, G = Key group, I = Ignore note off. uint noteParam = SoundArchiveReader.GetFlagValue(f, 4, 0); r.PercussionMode = (noteParam & 0xFF) > 0; r.KeyGroup = (byte)((noteParam & 0xFF00) >> 8); r.InterPolationType = (VelocityRegion.EInterPolationType)((noteParam & 0xFF0000) >> 16); //ADSHR curve offset. if (f.isFlagEnabled[9]) { //ADSHR not null. if (f.flagValues[9] != 0xFFFFFFFF) { //Jump to offset. FileReader.JumpToOffsetManually(br, (int)f.flagValues[9]); //Start structure. FileReader.StartStructure(br); //ADSHR curve reference is here. FileReader.OpenReference(br, "ADSHR"); //Not null reference. if (!FileReader.ReferenceIsNull("ADSHR")) { //Jump to position. FileReader.JumpToReference(br, "ADSHR"); //Read ADSHR curve. r.Attack = br.ReadByte(); r.Decay = br.ReadByte(); r.Sustain = br.ReadByte(); r.Hold = br.ReadByte(); r.Release = br.ReadByte(); } //End structure. FileReader.EndStructure(); //Close reference. FileReader.CloseReference("ADSHR"); } } //End structure. FileReader.EndStructure(); //Return the velocity region. return(r); }