removed unwanted bar now with waveforms, major updates

This commit is contained in:
Mark Gregory
2026-11-06 13:09:24 +00:00
parent 7b45184dff
commit f6368e4ae7
7 changed files with 243 additions and 41 deletions
+22 -4
View File
@@ -59,7 +59,22 @@ import CoreAudio
let first = AVAudioFramePosition(start*source.processingFormat.sampleRate)
let count = AVAudioFrameCount(max(1,min(source.length-first,AVAudioFramePosition((end-start)*source.processingFormat.sampleRate))))
guard let buffer = AVAudioPCMBuffer(pcmFormat:source.processingFormat,frameCapacity:count) else { throw LibraryError.message("Cannot prepare loop audio") }
source.framePosition = first;try source.read(into:buffer,frameCount:count);try Task.checkCancellation();return buffer
source.framePosition = first;try source.read(into:buffer,frameCount:count);try Task.checkCancellation()
// Meet the first sample at the loop seam without changing its beat length.
if let data = buffer.floatChannelData {
let frames = Int(buffer.frameLength),stride = Int(buffer.stride)
let blend = min(frames/4,Int(source.processingFormat.sampleRate*0.003))
if blend > 1 {
for channel in 0..<Int(source.processingFormat.channelCount) {
let samples = data[channel],head = samples[0]
for i in 0..<blend {
let mix = Float(i)/Float(blend-1),index = (frames-blend+i)*stride
samples[index] = samples[index]*(1-mix)+head*mix
}
}
}
}
return buffer
}
do {
let buffer = try await withTaskCancellationHandler(operation:{try await worker.value},onCancel:{worker.cancel()})
@@ -72,7 +87,7 @@ import CoreAudio
if let pending = self.pendingLoopSwitch,raw >= pending.at { activeRange = pending.range }
else { activeRange = self.scheduledLoop ?? start...end }
let remaining = max(0,activeRange.upperBound-self.loopPosition(raw))
self.node.scheduleBuffer(buffer,at:nil,options:[.loops,.interruptsAtLoop])
self.node.scheduleBuffer(buffer,at:nil,options:[.loops,.interruptsAtLoop],completionHandler:nil)
self.pendingLoopSwitch = (raw+remaining,start...end)
} else {
self.loopAudioRestartCount += 1
@@ -158,6 +173,9 @@ import CoreAudio
private var videoPlayer: AVPlayer?
private var videoOutput: AVPlayerItemVideoOutput?
private let videoContext = CIContext()
func useWaveformCache(at directory: URL) {
waveformTask?.cancel();waveformGeneration = UUID();waveformCacheDirectory = directory
}
private var mixURL: URL { waveformCacheDirectory.deletingLastPathComponent().appendingPathComponent("GlobalMixer.json") }
private var restoringMix = true
private var persistsMix = true
@@ -245,7 +263,7 @@ import CoreAudio
@Published private(set) var waveformUnavailable = false
@Published private(set) var waveformFromCache = false
@Published private(set) var waveformSaved = false
private let waveformCacheDirectory: URL
private var waveformCacheDirectory: URL
private var audioURL: URL?
var sourceAudioURL: URL? { audioURL }
private var waveformTask: Task<Void, Never>?
@@ -665,7 +683,7 @@ enum WaveformCache {
return analysis
}
static func save(_ analysis: AudioWaveform.Analysis,audio: URL,directory: URL) throws {
try FileManager.default.createDirectory(at:directory,withIntermediateDirectories:true)
try ManagedMediaStorage.prepare(directory)
let encoder = PropertyListEncoder();encoder.outputFormat = .binary
try encoder.encode(analysis).write(to:location(audio:audio,directory:directory),options:.atomic)
}