Skip to content
Permalink
Browse files

Merge remote-tracking branch 'origin/master-3.0'

  • Loading branch information
xen2 committed Nov 27, 2018
2 parents a3d3173 + 1c64796 commit 59290e7e19a24127f3198d5bf036c4aff3940ed6
@@ -96,8 +96,6 @@ public static AssetLogMessage From(Package package, IReference assetReference, I
{
assetLogMessage.Line = yamlException.Start.Line;
assetLogMessage.Character = yamlException.Start.Column;
// We've already got everything, no need to pollute log with stack trace of exception
assetLogMessage.Exception = null;
}

return assetLogMessage;
@@ -162,7 +162,10 @@ protected override void ReadDictionaryItems(ref ObjectContext objectContext)
if (objectContext.SerializerContext.AllowErrors)
{
var logger = objectContext.SerializerContext.Logger;
logger?.Warning("Ignored dictionary item that could not be deserialized", ex);
if(ex.InnerException is DefaultObjectFactory.InstanceCreationException ice)
logger?.Warning($"Ignored dictionary item that could not be deserialized:\n{ice.Message}", ex);
else
logger?.Warning($"Ignored dictionary item that could not be deserialized:\n{ex.Message}", ex);
objectContext.Reader.Skip(currentDepth, objectContext.Reader.Parser.Current == startParsingEvent);
}
else throw;
@@ -107,7 +107,25 @@ public object Create(Type type)
if (PrimitiveDescriptor.IsPrimitive(type) || type.IsArray)
return null;

return type.GetConstructor(EmptyTypes) != null || type.IsValueType ? Activator.CreateInstance(type) : null;
if (type.GetConstructor(EmptyTypes) != null || type.IsValueType)
{
try
{
return Activator.CreateInstance(type);
}
catch (Exception e)
{
//return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type);
throw new InstanceCreationException($"'{typeof(Activator)}' failed to create instance of type '{type}', see inner exception.", e);
}
}

return null;
}

public class InstanceCreationException : Exception
{
public InstanceCreationException(string message, Exception innerException) : base(message, innerException) { }
}
}
}
@@ -8,7 +8,18 @@ public abstract class ClassDataSerializer<T> : DataSerializer<T> where T : class
public override void PreSerialize(ref T obj, ArchiveMode mode, SerializationStream stream)
{
if (mode == ArchiveMode.Deserialize && obj == null)
obj = new T();
{
try
{
obj = new T();
}
catch (System.Exception)
{
//obj = (T)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(T));
//return;
throw;
}
}
}
}
}
@@ -39,6 +39,9 @@
<ToggleButton IsChecked="{Binding ShowFatalMessages, RelativeSource={RelativeSource Mode=TemplatedParent}}">
<Path Width="12" Height="12" Stretch="Uniform" Fill="{StaticResource TextBrush}" Data="{StaticResource GeometryFatalMessage}" />
</ToggleButton>
<ToggleButton IsChecked="{Binding ShowStacktrace, RelativeSource={RelativeSource Mode=TemplatedParent}}">
<Label Content="..." Width="12" Height="12" HorizontalContentAlignment="Center" />
</ToggleButton>
</ToolBar>
<ToolBar ToolBarTray.IsLocked="True" Header="Search:" Visibility="{Binding CanSearchLog, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={xk:VisibleOrCollapsed}}">
<xk:TextBox Width="150" UseTimedValidation="True" Text="{Binding SearchToken, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneWayToSource}" WatermarkContent="Search" />
@@ -113,6 +113,11 @@ static GridLogViewer()
/// </summary>
public static readonly DependencyProperty ShowFatalMessagesProperty = DependencyProperty.Register("ShowFatalMessages", typeof(bool), typeof(GridLogViewer), new PropertyMetadata(true, FilterPropertyChanged));

/// <summary>
/// Identifies the <see cref="ShowStacktrace"/> dependency property.
/// </summary>
public static readonly DependencyProperty ShowStacktraceProperty = DependencyProperty.Register("ShowStacktrace", typeof(bool), typeof(GridLogViewer), new PropertyMetadata(false, FilterPropertyChanged));

/// <summary>
/// Identifies the <see cref="Session"/> dependency property.
/// </summary>
@@ -183,6 +188,11 @@ static GridLogViewer()
/// </summary>
public bool ShowFatalMessages { get { return (bool)GetValue(ShowFatalMessagesProperty); } set { SetValue(ShowFatalMessagesProperty, value); } }

/// <summary>
/// Gets or sets whether the log viewer should display fatal messages.
/// </summary>
public bool ShowStacktrace { get { return (bool)GetValue(ShowStacktraceProperty); } set { SetValue(ShowStacktraceProperty, value); } }

/// <summary>
/// Gets or sets the session to use to select an asset related to a log message.
/// </summary>
@@ -34,7 +34,7 @@ protected class DecodeSoundFileCommand : AssetCommand<SoundAsset>
public DecodeSoundFileCommand(string url, SoundAsset parameters, IAssetFinder assetFinder)
: base(url, parameters, assetFinder)
{
Version = 1;
Version = 2;
}

/// <inheritdoc />
@@ -110,18 +110,25 @@ public override void SetLooped(bool loop)
looped = loop;
}

/// <summary>
/// Sets the range of the sound to play.
/// </summary>
/// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
public override void SetPlayRange(PlayRange range)
/// <inheritdoc/>
public override PlayRange PlayRange
{
lock (rangeLock)
get
{
playRange = range;
lock (rangeLock)
{
return playRange;
}
}
set
{
lock (rangeLock)
{
playRange = value;
}

base.SetPlayRange(range);
base.PlayRange = value;
}
}

protected override void InitializeInternal()
@@ -162,24 +169,36 @@ protected override void PrepareInternal()
// Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size)
var samplesToSkip = decoder.GetDecoderSampleDelay();

// Compute boundaries
var sampleBegin = (channels * samplesToSkip);
var sampleEnd = sampleBegin + (channels * samples);

var frameSize = SamplesPerFrame * channels;
//ok we need to handle this case properly, this means that the user wants to use a different then full audio stream range...
var sampleStart = (channels * samplesToSkip) + (int)Math.Floor(sampleRate * (double)channels * range.Start.TotalSeconds);
startPktSampleIndex = sampleStart % (frameSize);
var sampleStart = sampleBegin + (int)Math.Floor(sampleRate * (double)channels * range.Start.TotalSeconds);
// Make sure start is at least one sample before the end to avoid edge cases where startingPacketIndex == numberOfPackets
sampleStart = Math.Min(Math.Max(sampleStart, sampleBegin), sampleEnd - 1 * channels);

var sampleStop = (channels * samplesToSkip)
var sampleStop = sampleBegin
+ (range.Length != TimeSpan.Zero
? (int)Math.Floor(sampleRate * (double)channels * range.End.TotalSeconds)
: (channels * samples));
endPktSampleIndex = frameSize - sampleStop % frameSize;
// Make sure stop is at least one sample after start
sampleStop = Math.Min(Math.Max(sampleStop, sampleStart + 1 * channels), sampleEnd);

var skipCounter = startingPacketIndex = sampleStart / frameSize;
endPacketIndex = sampleStop / frameSize;
// Compute start/end packet
startingPacketIndex = sampleStart / frameSize;
endPacketIndex = (sampleStop - 1) / frameSize; // -1 to make sure we stay in last packet if using all of it

// How much data to use in start/end packet
startPktSampleIndex = sampleStart % (frameSize);
endPktSampleIndex = frameSize - sampleStop % frameSize;

// skip to the starting packet
if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex < endPacketIndex)
if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex <= endPacketIndex) // this shouldn't happen anymore with the min/max clamps
{
//valid offsets.. process it
var skipCounter = startingPacketIndex;
while (skipCounter-- > 0)
{
//skip data to reach starting packet
@@ -238,7 +257,7 @@ protected override unsafe void ExtractAndFillData()
for (var i = 0; i < passes; i++)
{
endingPacket = endPacketIndex == currentPacketIndex;

//read one packet, size first, then data
var len = reader.ReadInt16();
compressedSoundStream.Read(compressedBuffer, 0, len);
@@ -254,19 +273,11 @@ protected override unsafe void ExtractAndFillData()

if (endingPacket || compressedSoundStream.Position == compressedSoundStream.Length)
{
if (looped) //prepare again to play from begin
{
PrepareInternal();
}
else // stops the sound
{
StopInternal();
}

break;
}
}

// Send buffer to hardware
var finalPtr = new IntPtr(bufferPtr + (startingPacket ? startPktSampleIndex : 0));
var finalSize = (offset - (startingPacket ? startPktSampleIndex : 0) - (endingPacket ? endPktSampleIndex : 0)) * sizeof(short);

@@ -281,6 +292,19 @@ protected override unsafe void ExtractAndFillData()
begin = false;
}
FillBuffer(finalPtr, finalSize, bufferType);

// Go back to beginning if necessary
if (endingPacket || compressedSoundStream.Position == compressedSoundStream.Length)
{
if (looped) //prepare again to play from begin
{
PrepareInternal();
}
else // stops the sound
{
StopInternal(false);
}
}
}
}
}
@@ -167,12 +167,12 @@ public void Stop()
public bool IsPausedOrPlaying => playingQueued || state != PlayState.Stopped || isSourcePausedOrPlaying;

/// <summary>
/// Sets the region of time to play from the audio clip.
/// Gets or sets the region of time to play from the audio clip.
/// </summary>
/// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
public virtual void SetPlayRange(PlayRange range)
public virtual PlayRange PlayRange
{
Commands.Enqueue(AsyncCommand.SetRange);
get => new PlayRange(TimeSpan.Zero, TimeSpan.Zero);
set => Commands.Enqueue(AsyncCommand.SetRange);
}

/// <summary>
@@ -245,11 +245,12 @@ protected virtual void PauseInternal()
AudioLayer.SourcePause(soundInstance.Source);
}

protected virtual void StopInternal()
protected virtual void StopInternal(bool ignoreQueuedBuffer = true)
{
Ended.TrySetResult(true);
state = PlayState.Stopped;
AudioLayer.SourceStop(soundInstance.Source);
if (ignoreQueuedBuffer)
AudioLayer.SourceStop(soundInstance.Source);
RestartInternal();
}

@@ -397,7 +398,7 @@ private static unsafe void Worker()
continue;
}

if (source.CanFill)
if (source.CanFill && source.isSourcePausedOrPlaying)
source.ExtractAndFillData();
}

@@ -1589,6 +1589,19 @@ extern "C" {
void __stdcall OnLoopEnd(void* context) override;

void __stdcall OnVoiceError(void* context, HRESULT error) override;

void GetState(XAUDIO2_VOICE_STATE* state)
{
if (xnAudioWindows7Hacks)
{
auto win7Voice = reinterpret_cast<IXAudio2SourceVoice1*>(source_voice_);
win7Voice->GetState(state);
}
else
{
source_voice_->GetState(state, 0);
}
}
};

DLL_EXPORT_API xnAudioSource* xnAudioSourceCreate(xnAudioListener* listener, int sampleRate, int maxNBuffers, npBool mono, npBool spatialized, npBool streamed, npBool hrtf, float directionFactor, HrtfEnvironment environment)
@@ -1801,16 +1814,7 @@ extern "C" {
if(!source->streamed_ && !source->pause_)
{
XAUDIO2_VOICE_STATE state;
if (xnAudioWindows7Hacks)
{
auto win7Voice = reinterpret_cast<IXAudio2SourceVoice1*>(source->source_voice_);
win7Voice->GetState(&state);
}
else
{
source->source_voice_->GetState(&state, 0);
}

source->GetState(&state);
source->samplesAtBegin = state.SamplesPlayed;
}

@@ -1858,28 +1862,10 @@ extern "C" {
DLL_EXPORT_API double xnAudioSourceGetPosition(xnAudioSource* source)
{
XAUDIO2_VOICE_STATE state;
if(xnAudioWindows7Hacks)
{
auto win7Voice = reinterpret_cast<IXAudio2SourceVoice1*>(source->source_voice_);
win7Voice->GetState(&state);
}
else
{
source->source_voice_->GetState(&state, 0);
}
source->GetState(&state);

if (!source->streamed_)
{
auto elapsed = double(state.SamplesPlayed - source->samplesAtBegin) / double(source->sampleRate_);
auto singleBuffer = source->freeBuffers_[0];
auto length = singleBuffer->buffer_.PlayLength == 0 ?
double(singleBuffer->length_) / double(source->sampleRate_) :
double(singleBuffer->buffer_.PlayLength) / double(source->sampleRate_);
auto position = elapsed / length;
auto repeats = floor(position);
position = (position - repeats) * length;
return position;
}
return double(source->single_buffer_.PlayBegin + state.SamplesPlayed - source->samplesAtBegin) / double(source->sampleRate_);

//things work different for streamed sources, but anyway we simply subtract the snapshotted samples at begin of the stream ( could be the begin of the loop )
return double(state.SamplesPlayed - source->samplesAtBegin) / double(source->sampleRate_);
@@ -1971,15 +1957,7 @@ extern "C" {
{
//we need this info to compute position of stream
XAUDIO2_VOICE_STATE state;
if (xnAudioWindows7Hacks)
{
auto win7Voice = reinterpret_cast<IXAudio2SourceVoice1*>(source_voice_);
win7Voice->GetState(&state);
}
else
{
source_voice_->GetState(&state, 0);
}
GetState(&state);

samplesAtBegin = state.SamplesPlayed;
}
@@ -2009,6 +1987,13 @@ extern "C" {

void xnAudioSource::OnLoopEnd(void* context)
{
if (!streamed_)
{
XAUDIO2_VOICE_STATE state;
GetState(&state);

samplesAtBegin = state.SamplesPlayed;
}
}

DLL_EXPORT_API void xnAudioSourceQueueBuffer(xnAudioSource* source, xnAudioBuffer* buffer, short* pcm, int bufferSize, BufferType type)

0 comments on commit 59290e7

Please sign in to comment.
You can’t perform that action at this time.