From 0178b595c5352807cae73dd88c843d13ae545280 Mon Sep 17 00:00:00 2001 From: BleuBleu Date: Fri, 17 Jan 2025 21:56:37 +0800 Subject: [PATCH] Version bumps. --- Docs/docs/changelog.md | 6 + FamiStudio/Properties/AndroidManifest.xml | 2 +- FamiStudio/Properties/AssemblyInfo.cs | 4 +- .../Source/App/Droid/FamiStudioWindow.cs | 4 +- FamiStudio/Source/Project/Project.cs | 241 +++++++++--------- Setup/Setup.vdproj | 8 +- Setup/Version.txt | 2 +- 7 files changed, 139 insertions(+), 128 deletions(-) diff --git a/Docs/docs/changelog.md b/Docs/docs/changelog.md index 9c64d4f01..8707640d2 100644 --- a/Docs/docs/changelog.md +++ b/Docs/docs/changelog.md @@ -4,6 +4,12 @@ Version history / release notes for each release. To download older versions or view the release dates, please visit the [Github Releases](https://github.com/BleuBleu/FamiStudio/releases) page. +## Version 4.3.2 (Hotfix) + +Changes/Fixes: + +* Fixed crash when exporting audio/video + ## Version 4.3.1 (Hotfix) Changes/Fixes: diff --git a/FamiStudio/Properties/AndroidManifest.xml b/FamiStudio/Properties/AndroidManifest.xml index baaa7be8c..a04403fff 100644 --- a/FamiStudio/Properties/AndroidManifest.xml +++ b/FamiStudio/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@  - + diff --git a/FamiStudio/Properties/AssemblyInfo.cs b/FamiStudio/Properties/AssemblyInfo.cs index bbc8818ae..662db92f7 100644 --- a/FamiStudio/Properties/AssemblyInfo.cs +++ b/FamiStudio/Properties/AssemblyInfo.cs @@ -37,8 +37,8 @@ // The last digit is the BETA version number. When it is non-zero, the build and will be // interpreted as a development version. -[assembly: AssemblyVersion("4.3.1.0")] -[assembly: AssemblyFileVersion("4.3.1.0")] +[assembly: AssemblyVersion("4.3.2.0")] +[assembly: AssemblyFileVersion("4.3.2.0")] #if FAMISTUDIO_ANDROID // Add some common permissions, these can be removed if not needed diff --git a/FamiStudio/Source/App/Droid/FamiStudioWindow.cs b/FamiStudio/Source/App/Droid/FamiStudioWindow.cs index 3c2aa29a3..33e3ea849 100644 --- a/FamiStudio/Source/App/Droid/FamiStudioWindow.cs +++ b/FamiStudio/Source/App/Droid/FamiStudioWindow.cs @@ -786,7 +786,7 @@ public override bool OnTouchEvent(MotionEvent e) { if (!IsAsyncFileActivityInProgress) { - Debug.WriteLine($"OnTouchEvent {e.Action.ToString()} ({e.GetX()}, {e.GetY()})"); + //Debug.WriteLine($"OnTouchEvent {e.Action.ToString()} ({e.GetX()}, {e.GetY()})"); if (e.Action == MotionEventActions.Up) { @@ -832,7 +832,7 @@ public bool OnDown(MotionEvent e) { if (!IsAsyncFileActivityInProgress) { - Debug.WriteLine($"OnDown {e.PointerCount} ({e.GetX()}, {e.GetY()})"); + //Debug.WriteLine($"OnDown {e.PointerCount} ({e.GetX()}, {e.GetY()})"); lock (renderLock) { var ctrl = GetCapturedControlAtCoord((int)e.GetX(), (int)e.GetY(), out var x, out var y); diff --git a/FamiStudio/Source/Project/Project.cs b/FamiStudio/Source/Project/Project.cs index 2d03af9a7..34a613dc8 100644 --- a/FamiStudio/Source/Project/Project.cs +++ b/FamiStudio/Source/Project/Project.cs @@ -1970,175 +1970,180 @@ public unsafe bool AutoAssignN163WavePositions(out Dictionary wavePosi return true; } - var numN163Instruments = instruments.Count(i => i.IsN163); - var numN163AutoPos = instruments.Count(i => i.IsN163 && i.N163WaveAutoPos); - - if (numN163AutoPos == 0) - { - wavePositions = null; - return true; - } + // HACK : Last minute hack, when exporting we spawn multiple WavPlayer threads and + // those may end up all in this functions. + lock (this) + { + var numN163Instruments = instruments.Count(i => i.IsN163); + var numN163AutoPos = instruments.Count(i => i.IsN163 && i.N163WaveAutoPos); + + if (numN163AutoPos == 0) + { + wavePositions = null; + return true; + } - //var A = Platform.TimeSeconds(); + //var A = Platform.TimeSeconds(); - const int numBitsPerLong = sizeof(ulong) * 8; + const int numBitsPerLong = sizeof(ulong) * 8; - var instrumentOverlaps = new Dictionary>(numN163AutoPos); + var instrumentOverlaps = new Dictionary>(numN163AutoPos); - foreach (var song in songs) - { - var numFrames = song.EndLocation.ToAbsoluteNoteIndex(song); - var numLongs = Utils.DivideAndRoundUp(numFrames, numBitsPerLong); - var instrumentMasks = new Dictionary(numN163Instruments); - - // Buld a huge bitmask that tells us which frame each instrument is used. - // This is a bit overkill, but is very simple. - for (var i = 0; i < expansionNumN163Channels; i++) + foreach (var song in songs) { - var channel = song.GetChannelByType(ChannelType.N163Wave1 + i); + var numFrames = song.EndLocation.ToAbsoluteNoteIndex(song); + var numLongs = Utils.DivideAndRoundUp(numFrames, numBitsPerLong); + var instrumentMasks = new Dictionary(numN163Instruments); - // TODO : This ignores FamiTracker delayed cuts, so it may generate sub-optimal results when they are used. - for (var it = channel.GetSparseNoteIterator(song.StartLocation, song.EndLocation, NoteFilter.Musical); !it.Done; it.Next()) + // Buld a huge bitmask that tells us which frame each instrument is used. + // This is a bit overkill, but is very simple. + for (var i = 0; i < expansionNumN163Channels; i++) { - var note = it.Note; + var channel = song.GetChannelByType(ChannelType.N163Wave1 + i); - if (note.Instrument != null) + // TODO : This ignores FamiTracker delayed cuts, so it may generate sub-optimal results when they are used. + for (var it = channel.GetSparseNoteIterator(song.StartLocation, song.EndLocation, NoteFilter.Musical); !it.Done; it.Next()) { - if (!instrumentMasks.TryGetValue(note.Instrument, out var mask)) + var note = it.Note; + + if (note.Instrument != null) { - mask = new N163Mask(numLongs); - instrumentMasks.Add(note.Instrument, mask); - } + if (!instrumentMasks.TryGetValue(note.Instrument, out var mask)) + { + mask = new N163Mask(numLongs); + instrumentMasks.Add(note.Instrument, mask); + } - // Start + end of this note, in frame. - var idx1 = it.Location.ToAbsoluteNoteIndex(song); - var idx2 = Math.Min(idx1 + Math.Min(note.Duration, it.DistanceToNextNote), numFrames - 1); + // Start + end of this note, in frame. + var idx1 = it.Location.ToAbsoluteNoteIndex(song); + var idx2 = Math.Min(idx1 + Math.Min(note.Duration, it.DistanceToNextNote), numFrames - 1); - var long1 = idx1 / numBitsPerLong; - var long2 = idx2 / numBitsPerLong; - var bit1 = idx1 % numBitsPerLong; - var bit2 = idx2 % numBitsPerLong; + var long1 = idx1 / numBitsPerLong; + var long2 = idx2 / numBitsPerLong; + var bit1 = idx1 % numBitsPerLong; + var bit2 = idx2 % numBitsPerLong; - var mask1 = ~((1ul << bit1) - 1ul); - var mask2 = ((1ul << bit2) - 1ul); + var mask1 = ~((1ul << bit1) - 1ul); + var mask2 = ((1ul << bit2) - 1ul); - mask.MinIndex = Math.Min(long1, mask.MinIndex); - mask.MaxIndex = Math.Max(long2, mask.MaxIndex); + mask.MinIndex = Math.Min(long1, mask.MinIndex); + mask.MaxIndex = Math.Max(long2, mask.MaxIndex); - if (long1 == long2) - { - mask.Bits[long1] |= (mask1 & mask2); - } - else - { - mask.Bits[long1] |= mask1; - mask.Bits[long2] |= mask2; + if (long1 == long2) + { + mask.Bits[long1] |= (mask1 & mask2); + } + else + { + mask.Bits[long1] |= mask1; + mask.Bits[long2] |= mask2; - for (var j = long1 + 1; j < long2; j++) - mask.Bits[j] = ulong.MaxValue; + for (var j = long1 + 1; j < long2; j++) + mask.Bits[j] = ulong.MaxValue; + } } } } - } - - // Then "AND" these masks to figure out which instruments overlap, update the map of overlaps. - // We create overlaps both ways, so this is O(N^2/2) i guess. - var it1 = instrumentMasks.GetEnumerator(); - while (it1.MoveNext()) - { - var inst1 = it1.Current.Key; - var mask1 = it1.Current.Value; - var it2 = it1; - while (it2.MoveNext()) + // Then "AND" these masks to figure out which instruments overlap, update the map of overlaps. + // We create overlaps both ways, so this is O(N^2/2) i guess. + var it1 = instrumentMasks.GetEnumerator(); + while (it1.MoveNext()) { - var inst2 = it2.Current.Key; - var mask2 = it2.Current.Value; + var inst1 = it1.Current.Key; + var mask1 = it1.Current.Value; - if ((inst1.N163WaveAutoPos || inst2.N163WaveAutoPos) && - (mask1.MaxIndex >= mask1.MinIndex) && - (mask2.MaxIndex >= mask2.MinIndex)) + var it2 = it1; + while (it2.MoveNext()) { - var idx1 = Math.Max(mask1.MinIndex, mask2.MinIndex); - var idx2 = Math.Min(mask1.MaxIndex, mask2.MaxIndex); + var inst2 = it2.Current.Key; + var mask2 = it2.Current.Value; - for (var i = idx1; i <= idx2; i++) + if ((inst1.N163WaveAutoPos || inst2.N163WaveAutoPos) && + (mask1.MaxIndex >= mask1.MinIndex) && + (mask2.MaxIndex >= mask2.MinIndex)) { - if ((mask1.Bits[i] & mask2.Bits[i]) != 0) + var idx1 = Math.Max(mask1.MinIndex, mask2.MinIndex); + var idx2 = Math.Min(mask1.MaxIndex, mask2.MaxIndex); + + for (var i = idx1; i <= idx2; i++) { - if (inst1.N163WaveAutoPos) + if ((mask1.Bits[i] & mask2.Bits[i]) != 0) { - if (!instrumentOverlaps.TryGetValue(inst1, out var set1)) + if (inst1.N163WaveAutoPos) { - set1 = new HashSet(numN163Instruments); - instrumentOverlaps.Add(inst1, set1); + if (!instrumentOverlaps.TryGetValue(inst1, out var set1)) + { + set1 = new HashSet(numN163Instruments); + instrumentOverlaps.Add(inst1, set1); + } + set1.Add(inst2); } - set1.Add(inst2); - } - if (inst2.N163WaveAutoPos) - { - if (!instrumentOverlaps.TryGetValue(inst2, out var set2)) + if (inst2.N163WaveAutoPos) { - set2 = new HashSet(numN163Instruments); - instrumentOverlaps.Add(inst2, set2); + if (!instrumentOverlaps.TryGetValue(inst2, out var set2)) + { + set2 = new HashSet(numN163Instruments); + instrumentOverlaps.Add(inst2, set2); + } + set2.Add(inst1); } - set2.Add(inst1); + break; } - break; } } } } } - } - // Finally, try to assign the wave positions without generating overlap. - // TODO : Sort instrument by descending wav size + how much they are used maybe? - wavePositions = new Dictionary(numN163AutoPos); + // Finally, try to assign the wave positions without generating overlap. + // TODO : Sort instrument by descending wav size + how much they are used maybe? + wavePositions = new Dictionary(numN163AutoPos); - var maxPos = N163WaveRAMSize * 2; - var overlapDetected = false; - - foreach (var kv in instrumentOverlaps) - { - var inst1 = kv.Key; - var pos1 = 0; - var overlapInstruments = kv.Value; + var maxPos = N163WaveRAMSize * 2; + var overlapDetected = false; - foreach (var inst2 in overlapInstruments) + foreach (var kv in instrumentOverlaps) { - var pos2 = (int)inst2.N163WavePos; + var inst1 = kv.Key; + var pos1 = 0; + var overlapInstruments = kv.Value; - // No position assigned yet, will be done later. - if (inst2.N163WaveAutoPos && !wavePositions.TryGetValue(inst2.Id, out pos2)) + foreach (var inst2 in overlapInstruments) { - continue; - } + var pos2 = (int)inst2.N163WavePos; - // If overlap, try again right after this instrument. - if (pos1 + inst1.N163WaveSize > pos2 && - pos2 + inst2.N163WaveSize > pos1) - { - pos1 = pos2 + inst2.N163WaveSize; + // No position assigned yet, will be done later. + if (inst2.N163WaveAutoPos && !wavePositions.TryGetValue(inst2.Id, out pos2)) + { + continue; + } - // Was not able to allocate. - if (pos1 + inst1.N163WaveSize > maxPos) + // If overlap, try again right after this instrument. + if (pos1 + inst1.N163WaveSize > pos2 && + pos2 + inst2.N163WaveSize > pos1) { - Log.LogMessage(LogSeverity.Warning, $"Not able to assign a N163 wave position to instrument '{inst1.Name}', reduce wave size or minimize overlap with other instruments. Setting to 0."); - pos1 = 0; - overlapDetected = true; - break; + pos1 = pos2 + inst2.N163WaveSize; + + // Was not able to allocate. + if (pos1 + inst1.N163WaveSize > maxPos) + { + Log.LogMessage(LogSeverity.Warning, $"Not able to assign a N163 wave position to instrument '{inst1.Name}', reduce wave size or minimize overlap with other instruments. Setting to 0."); + pos1 = 0; + overlapDetected = true; + break; + } } } - } - wavePositions.Add(inst1.Id, pos1); - } + wavePositions.Add(inst1.Id, pos1); + } - //var B = Platform.TimeSeconds(); - //Trace.WriteLine($"ASSIGN TIME! {(B - A) * 1000} ms"); + //var B = Platform.TimeSeconds(); + //Trace.WriteLine($"ASSIGN TIME! {(B - A) * 1000} ms"); - return !overlapDetected; + return !overlapDetected; + } } public int FindLargestUniqueId() diff --git a/Setup/Setup.vdproj b/Setup/Setup.vdproj index cc351d322..7453bb4f3 100644 --- a/Setup/Setup.vdproj +++ b/Setup/Setup.vdproj @@ -1086,15 +1086,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:FamiStudio" - "ProductCode" = "8:{358D062E-06E8-41C1-ADAB-5B70CC8F3E89}" - "PackageCode" = "8:{C5925232-0F9F-4BB0-9526-CD51C16F9301}" + "ProductCode" = "8:{837BBC62-64A8-4FF9-9485-A8EFC6F7E7C9}" + "PackageCode" = "8:{7861A106-E418-42EF-A8CC-E2B106B95C5B}" "UpgradeCode" = "8:{B82EE4DC-4ECE-46C8-A464-1B7CAE09B938}" "AspNetVersion" = "8:4.0.30319.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:4.3.1" + "ProductVersion" = "8:4.3.2" "Manufacturer" = "8:BleuBleu" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:https://famistudio.org/doc/install/" @@ -1664,7 +1664,7 @@ } "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_9A9A290F02BD4DF9857CA1EFF73548B4" { - "SourcePath" = "8:..\\FamiStudio\\obj\\Release\\net8.0\\apphost.exe" + "SourcePath" = "8:..\\FamiStudio\\obj\\Debug\\net8.0\\apphost.exe" "TargetName" = "8:" "Tag" = "8:" "Folder" = "8:_35E89725F8BA48E0AC14F44C8E513BED" diff --git a/Setup/Version.txt b/Setup/Version.txt index bc56e7649..66e214a2e 100644 --- a/Setup/Version.txt +++ b/Setup/Version.txt @@ -1 +1 @@ -431 \ No newline at end of file +432 \ No newline at end of file