Exemplo n.º 1
0
		public XactClip (SoundBank soundBank, BinaryReader clipReader)
		{
            State = SoundState.Stopped;

		    var volumeDb = XactHelpers.ParseDecibels(clipReader.ReadByte());
            _defaultVolume = XactHelpers.ParseVolumeFromDecibels(volumeDb);
            var clipOffset = clipReader.ReadUInt32();

            // Unknown!
            clipReader.ReadUInt32();

			var oldPosition = clipReader.BaseStream.Position;
			clipReader.BaseStream.Seek(clipOffset, SeekOrigin.Begin);
			
			var numEvents = clipReader.ReadByte();
			_events = new ClipEvent[numEvents];
			
			for (var i=0; i<numEvents; i++) 
            {
				var eventInfo = clipReader.ReadUInt32();
                var randomOffset = clipReader.ReadUInt16() * 0.001f;

                // TODO: eventInfo still has 11 bits that are unknown!
				var eventId = eventInfo & 0x1F;
                var timeStamp = ((eventInfo >> 5) & 0xFFFF) * 0.001f;
                var unknown = eventInfo >> 21;

				switch (eventId) {
                case 0:
                    // Stop Event
                    throw new NotImplementedException("Stop event");

				case 1:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var playRelease = (eventFlags & 0x01) == 0x01;
                    var panEnabled = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

					int trackIndex = clipReader.ReadUInt16();
                    int waveBankIndex = clipReader.ReadByte();					
					var loopCount = clipReader.ReadByte();
                    var panAngle = clipReader.ReadUInt16() / 100.0f;
                    var panArc = clipReader.ReadUInt16() / 100.0f;
                    
                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp, 
                        randomOffset,
                        soundBank, 
                        new[] { waveBankIndex }, 
                        new[] { trackIndex },
                        null,
                        0,
                        VariationType.Ordered, 
                        null,
                        null,
                        loopCount,
                        false);

					break;
                }

                case 3:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var playRelease = (eventFlags & 0x01) == 0x01;
                    var panEnabled = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    var loopCount = clipReader.ReadByte();
                    var panAngle = clipReader.ReadUInt16() / 100.0f;
                    var panArc = clipReader.ReadUInt16() / 100.0f;

                    // The number of tracks for the variations.
                    var numTracks = clipReader.ReadUInt16();

                    // Not sure what most of this is.
                    var moreFlags = clipReader.ReadByte();
                    var newWaveOnLoop = (moreFlags & 0x40) == 0x40;
                    
                    // The variation playlist type seems to be 
                    // stored in the bottom 4bits only.
                    var variationType = (VariationType)(moreFlags & 0x0F);

                    // Unknown!
                    clipReader.ReadBytes(5);

                    // Read in the variation playlist.
                    var waveBanks = new int[numTracks];
                    var tracks = new int[numTracks];
                    var weights = new byte[numTracks];
                    var totalWeights = 0;
                    for (var j = 0; j < numTracks; j++)
                    {
                        tracks[j] = clipReader.ReadUInt16();
                        waveBanks[j] = clipReader.ReadByte();
                        var minWeight = clipReader.ReadByte();
                        var maxWeight = clipReader.ReadByte();
                        weights[j] = (byte)(maxWeight - minWeight);
                        totalWeights += weights[j];
                    }

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank, 
                        waveBanks, 
                        tracks,
                        weights,
                        totalWeights,
                        variationType,
                        null,
                        null,
                        loopCount,
                        newWaveOnLoop);

                    break;
                }

                case 4:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var playRelease = (eventFlags & 0x01) == 0x01;
                    var panEnabled = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    int trackIndex = clipReader.ReadUInt16();
                    int waveBankIndex = clipReader.ReadByte();
                    var loopCount = clipReader.ReadByte();
                    var panAngle = clipReader.ReadUInt16() / 100.0f;
                    var panArc = clipReader.ReadUInt16() / 100.0f;

                    // Pitch variation range
                    var minPitch = clipReader.ReadInt16() / 1000.0f;
                    var maxPitch = clipReader.ReadInt16() / 1000.0f;

                    // Volume variation range
                    var minVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());
                    var maxVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());

                    // Filter variation
                    var minFrequency = clipReader.ReadSingle() / 1000.0f;
                    var maxFrequency = clipReader.ReadSingle() / 1000.0f;
                    var minQ = clipReader.ReadSingle();
                    var maxQ = clipReader.ReadSingle();

                    // Unknown!
                    clipReader.ReadByte();

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        new[] { waveBankIndex },
                        new[] { trackIndex }, 
                        null,
                        0,
                        VariationType.Ordered,
                        new Vector2(minVolume, maxVolume - minVolume),
                        new Vector2(minPitch, maxPitch - minPitch), 
                        loopCount,
                        false);

                    break;
                }

                case 6:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var playRelease = (eventFlags & 0x01) == 0x01;
                    var panEnabled = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    var loopCount = clipReader.ReadByte();
                    var panAngle = clipReader.ReadUInt16() / 100.0f;
                    var panArc = clipReader.ReadUInt16() / 100.0f;

                    // Pitch variation range
                    var minPitch = clipReader.ReadInt16() / 1000.0f;
                    var maxPitch = clipReader.ReadInt16() / 1000.0f;

                    // Volume variation range
                    var minVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());
                    var maxVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());

                    // Filter variation range
                    var minFrequency = clipReader.ReadSingle() / 1000.0f;
                    var maxFrequency = clipReader.ReadSingle() / 1000.0f;
                    var minQ = clipReader.ReadSingle();
                    var maxQ = clipReader.ReadSingle();

                    // Unknown!
                    clipReader.ReadByte();

                    // TODO: Still has unknown bits!
                    var variationFlags = clipReader.ReadByte();

                    // Enable pitch variation
                    Vector2? pitchVar = null;
                    if ((variationFlags & 0x10) == 0x10)
                        pitchVar = new Vector2(minPitch, maxPitch - minPitch);

                    // Enable volume variation
                    Vector2? volumeVar = null;
                    if ((variationFlags & 0x20) == 0x20)
                        volumeVar = new Vector2(minVolume, maxVolume - minVolume);

                    // Enable filter variation
                    Vector4? filterVar = null;
                    if ((variationFlags & 0x40) == 0x40)
                        filterVar = new Vector4(minFrequency, maxFrequency - minFrequency, minQ, maxQ - minQ);

                    // The number of tracks for the variations.
                    var numTracks = clipReader.ReadUInt16();

                    // Not sure what most of this is.
                    var moreFlags = clipReader.ReadByte();
                    var newWaveOnLoop = (moreFlags & 0x40) == 0x40;

                    // The variation playlist type seems to be 
                    // stored in the bottom 4bits only.
                    var variationType = (VariationType)(moreFlags & 0x0F);

                    // Unknown!
                    clipReader.ReadBytes(5);

                    // Read in the variation playlist.
                    var waveBanks = new int[numTracks];
                    var tracks = new int[numTracks];
                    var weights = new byte[numTracks];
                    var totalWeights = 0;
                    for (var j = 0; j < numTracks; j++)
                    {
                        tracks[j] = clipReader.ReadUInt16();
                        waveBanks[j] = clipReader.ReadByte();
                        var minWeight = clipReader.ReadByte();
                        var maxWeight = clipReader.ReadByte();
                        weights[j] = (byte)(maxWeight - minWeight);
                        totalWeights += weights[j];
                    }

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        waveBanks,
                        tracks,
                        weights,
                        totalWeights,
                        variationType,
                        volumeVar,
                        pitchVar, 
                        loopCount,
                        newWaveOnLoop);

                    break;
                }

                case 7:
                    // Pitch Event
                    throw new NotImplementedException("Pitch event");

                case 8:
                {
                    // Unknown!
                    clipReader.ReadBytes(2);

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var isAdd = (eventFlags & 0x01) == 0x01;

                    // The replacement or additive volume.
                    var decibles = clipReader.ReadSingle() / 100.0f;
                    var volume = XactHelpers.ParseVolumeFromDecibels(decibles + (isAdd ? volumeDb : 0));

                    // Unknown!
                    clipReader.ReadBytes(9);

                    _events[i] = new VolumeEvent(   this, 
                                                    timeStamp, 
                                                    randomOffset, 
                                                    volume);
                    break;
                }

                case 17:
                    // Volume Repeat Event
                    throw new NotImplementedException("Volume repeat event");

                case 9:
                    // Marker Event
                    throw new NotImplementedException("Marker event");

				default:
                    throw new NotSupportedException("Unknown event " + eventId);
				}
			}
			
			clipReader.BaseStream.Seek (oldPosition, SeekOrigin.Begin);
		}
Exemplo n.º 2
0
        public XactClip(SoundBank soundBank, BinaryReader clipReader)
        {
            State = SoundState.Stopped;

            var volumeDb = XactHelpers.ParseDecibels(clipReader.ReadByte());

            _defaultVolume = XactHelpers.ParseVolumeFromDecibels(volumeDb);
            var clipOffset = clipReader.ReadUInt32();

            // Unknown!
            clipReader.ReadUInt32();

            var oldPosition = clipReader.BaseStream.Position;

            clipReader.BaseStream.Seek(clipOffset, SeekOrigin.Begin);

            var numEvents = clipReader.ReadByte();

            _events = new ClipEvent[numEvents];

            for (var i = 0; i < numEvents; i++)
            {
                var eventInfo    = clipReader.ReadUInt32();
                var randomOffset = clipReader.ReadUInt16() * 0.001f;

                // TODO: eventInfo still has 11 bits that are unknown!
                var eventId   = eventInfo & 0x1F;
                var timeStamp = ((eventInfo >> 5) & 0xFFFF) * 0.001f;
                var unknown   = eventInfo >> 21;

                switch (eventId)
                {
                case 0:
                    // Stop Event
                    throw new NotImplementedException("Stop event");

                case 1:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags       = clipReader.ReadByte();
                    var playRelease      = (eventFlags & 0x01) == 0x01;
                    var panEnabled       = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    int trackIndex    = clipReader.ReadUInt16();
                    int waveBankIndex = clipReader.ReadByte();
                    var loopCount     = clipReader.ReadByte();
                    var panAngle      = clipReader.ReadUInt16() / 100.0f;
                    var panArc        = clipReader.ReadUInt16() / 100.0f;

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        new[] { waveBankIndex },
                        new[] { trackIndex },
                        null,
                        0,
                        VariationType.Ordered,
                        null,
                        null,
                        loopCount,
                        false);

                    break;
                }

                case 3:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags       = clipReader.ReadByte();
                    var playRelease      = (eventFlags & 0x01) == 0x01;
                    var panEnabled       = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    var loopCount = clipReader.ReadByte();
                    var panAngle  = clipReader.ReadUInt16() / 100.0f;
                    var panArc    = clipReader.ReadUInt16() / 100.0f;

                    // The number of tracks for the variations.
                    var numTracks = clipReader.ReadUInt16();

                    // Not sure what most of this is.
                    var moreFlags     = clipReader.ReadByte();
                    var newWaveOnLoop = (moreFlags & 0x40) == 0x40;

                    // The variation playlist type seems to be
                    // stored in the bottom 4bits only.
                    var variationType = (VariationType)(moreFlags & 0x0F);

                    // Unknown!
                    clipReader.ReadBytes(5);

                    // Read in the variation playlist.
                    var waveBanks    = new int[numTracks];
                    var tracks       = new int[numTracks];
                    var weights      = new byte[numTracks];
                    var totalWeights = 0;
                    for (var j = 0; j < numTracks; j++)
                    {
                        tracks[j]    = clipReader.ReadUInt16();
                        waveBanks[j] = clipReader.ReadByte();
                        var minWeight = clipReader.ReadByte();
                        var maxWeight = clipReader.ReadByte();
                        weights[j]    = (byte)(maxWeight - minWeight);
                        totalWeights += weights[j];
                    }

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        waveBanks,
                        tracks,
                        weights,
                        totalWeights,
                        variationType,
                        null,
                        null,
                        loopCount,
                        newWaveOnLoop);

                    break;
                }

                case 4:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags       = clipReader.ReadByte();
                    var playRelease      = (eventFlags & 0x01) == 0x01;
                    var panEnabled       = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    int trackIndex    = clipReader.ReadUInt16();
                    int waveBankIndex = clipReader.ReadByte();
                    var loopCount     = clipReader.ReadByte();
                    var panAngle      = clipReader.ReadUInt16() / 100.0f;
                    var panArc        = clipReader.ReadUInt16() / 100.0f;

                    // Pitch variation range
                    var minPitch = clipReader.ReadInt16() / 1000.0f;
                    var maxPitch = clipReader.ReadInt16() / 1000.0f;

                    // Volume variation range
                    var minVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());
                    var maxVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());

                    // Filter variation
                    var minFrequency = clipReader.ReadSingle() / 1000.0f;
                    var maxFrequency = clipReader.ReadSingle() / 1000.0f;
                    var minQ         = clipReader.ReadSingle();
                    var maxQ         = clipReader.ReadSingle();

                    // Unknown!
                    clipReader.ReadByte();

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        new[] { waveBankIndex },
                        new[] { trackIndex },
                        null,
                        0,
                        VariationType.Ordered,
                        new Vector2(minVolume, maxVolume - minVolume),
                        new Vector2(minPitch, maxPitch - minPitch),
                        loopCount,
                        false);

                    break;
                }

                case 6:
                {
                    // Unknown!
                    clipReader.ReadByte();

                    // Event flags
                    var eventFlags       = clipReader.ReadByte();
                    var playRelease      = (eventFlags & 0x01) == 0x01;
                    var panEnabled       = (eventFlags & 0x02) == 0x02;
                    var useCenterSpeaker = (eventFlags & 0x04) == 0x04;

                    var loopCount = clipReader.ReadByte();
                    var panAngle  = clipReader.ReadUInt16() / 100.0f;
                    var panArc    = clipReader.ReadUInt16() / 100.0f;

                    // Pitch variation range
                    var minPitch = clipReader.ReadInt16() / 1000.0f;
                    var maxPitch = clipReader.ReadInt16() / 1000.0f;

                    // Volume variation range
                    var minVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());
                    var maxVolume = XactHelpers.ParseVolumeFromDecibels(clipReader.ReadByte());

                    // Filter variation range
                    var minFrequency = clipReader.ReadSingle() / 1000.0f;
                    var maxFrequency = clipReader.ReadSingle() / 1000.0f;
                    var minQ         = clipReader.ReadSingle();
                    var maxQ         = clipReader.ReadSingle();

                    // Unknown!
                    clipReader.ReadByte();

                    // TODO: Still has unknown bits!
                    var variationFlags = clipReader.ReadByte();

                    // Enable pitch variation
                    Vector2?pitchVar = null;
                    if ((variationFlags & 0x10) == 0x10)
                    {
                        pitchVar = new Vector2(minPitch, maxPitch - minPitch);
                    }

                    // Enable volume variation
                    Vector2?volumeVar = null;
                    if ((variationFlags & 0x20) == 0x20)
                    {
                        volumeVar = new Vector2(minVolume, maxVolume - minVolume);
                    }

                    // Enable filter variation
                    Vector4?filterVar = null;
                    if ((variationFlags & 0x40) == 0x40)
                    {
                        filterVar = new Vector4(minFrequency, maxFrequency - minFrequency, minQ, maxQ - minQ);
                    }

                    // The number of tracks for the variations.
                    var numTracks = clipReader.ReadUInt16();

                    // Not sure what most of this is.
                    var moreFlags     = clipReader.ReadByte();
                    var newWaveOnLoop = (moreFlags & 0x40) == 0x40;

                    // The variation playlist type seems to be
                    // stored in the bottom 4bits only.
                    var variationType = (VariationType)(moreFlags & 0x0F);

                    // Unknown!
                    clipReader.ReadBytes(5);

                    // Read in the variation playlist.
                    var waveBanks    = new int[numTracks];
                    var tracks       = new int[numTracks];
                    var weights      = new byte[numTracks];
                    var totalWeights = 0;
                    for (var j = 0; j < numTracks; j++)
                    {
                        tracks[j]    = clipReader.ReadUInt16();
                        waveBanks[j] = clipReader.ReadByte();
                        var minWeight = clipReader.ReadByte();
                        var maxWeight = clipReader.ReadByte();
                        weights[j]    = (byte)(maxWeight - minWeight);
                        totalWeights += weights[j];
                    }

                    _events[i] = new PlayWaveEvent(
                        this,
                        timeStamp,
                        randomOffset,
                        soundBank,
                        waveBanks,
                        tracks,
                        weights,
                        totalWeights,
                        variationType,
                        volumeVar,
                        pitchVar,
                        loopCount,
                        newWaveOnLoop);

                    break;
                }

                case 7:
                    // Pitch Event
                    throw new NotImplementedException("Pitch event");

                case 8:
                {
                    // Unknown!
                    clipReader.ReadBytes(2);

                    // Event flags
                    var eventFlags = clipReader.ReadByte();
                    var isAdd      = (eventFlags & 0x01) == 0x01;

                    // The replacement or additive volume.
                    var decibles = clipReader.ReadSingle() / 100.0f;
                    var volume   = XactHelpers.ParseVolumeFromDecibels(decibles + (isAdd ? volumeDb : 0));

                    // Unknown!
                    clipReader.ReadBytes(9);

                    _events[i] = new VolumeEvent(this,
                                                 timeStamp,
                                                 randomOffset,
                                                 volume);
                    break;
                }

                case 17:
                    // Volume Repeat Event
                    throw new NotImplementedException("Volume repeat event");

                case 9:
                    // Marker Event
                    throw new NotImplementedException("Marker event");

                default:
                    throw new NotSupportedException("Unknown event " + eventId);
                }
            }

            clipReader.BaseStream.Seek(oldPosition, SeekOrigin.Begin);
        }