broken changes
This commit is contained in:
@@ -20,6 +20,16 @@ struct DJAudioRouting: Codable, Equatable {
|
||||
if mode == "Internal",device.outputChannels >= 4 { routing.cue = .init(uid:device.uid,firstChannel:2) }
|
||||
return routing
|
||||
}
|
||||
func changingMode(_ mode: String,preferred: DJAudioDevice?) -> Self {
|
||||
var next = self;next.mode = mode
|
||||
if mode == "External" {
|
||||
if next.deckA == DJAudioRoute(),next.deckB == DJAudioRoute(),let preferred {
|
||||
next.deckA = .init(uid:preferred.uid,firstChannel:0);next.deckB = .init(uid:preferred.uid,firstChannel:2)
|
||||
}
|
||||
if !next.cue.uid.isEmpty,[next.deckA,next.deckB].contains(next.cue) { next.cue = .init() }
|
||||
}
|
||||
return next
|
||||
}
|
||||
static func channelMap(channels: Int,first: Int) throws -> [Int32] {
|
||||
guard channels >= 2,first >= 0,first % 2 == 0,first+1 < channels else { throw LibraryError.message("Choose an available stereo channel pair.") }
|
||||
var map = [Int32](repeating:-1,count:channels);map[first] = 0;map[first+1] = 1;return map
|
||||
@@ -67,7 +77,7 @@ struct DJAudioDevicesPane: View {
|
||||
VStack(alignment:.leading,spacing:22) {
|
||||
PreferencesSection("Audio Routing") {
|
||||
VStack(spacing:22) {
|
||||
HStack { Text("Mixer Mode:").frame(width:130,alignment:.trailing);Picker("Mixer Mode",selection:$draft.mode) { Text("Internal").tag("Internal");Text("External").tag("External") }.pickerStyle(.radioGroup).horizontalRadioGroupLayout().labelsHidden();Spacer() }
|
||||
HStack { Text("Mixer Mode:").frame(width:130,alignment:.trailing);Picker("Mixer Mode",selection:Binding(get:{draft.mode},set:{draft = draft.changingMode($0,preferred:recommended)})) { Text("Internal").tag("Internal");Text("External").tag("External") }.pickerStyle(.radioGroup).horizontalRadioGroupLayout().labelsHidden();Spacer() }
|
||||
if draft.mode == "Internal" { row("Main Output",route:$draft.main,icon:"hifispeaker.fill") }
|
||||
else { row("Deck A",route:$draft.deckA,icon:"a.circle");row("Deck B",route:$draft.deckB,icon:"b.circle") }
|
||||
row("Pre-Cueing",route:$draft.cue,icon:"headphones",optional:true)
|
||||
@@ -76,7 +86,7 @@ struct DJAudioDevicesPane: View {
|
||||
}
|
||||
if let recommended {
|
||||
Button("Use \(recommended.name)") { draft = .controllerPreset(recommended,mode:draft.mode) }
|
||||
.help("Set up the controller’s stereo pairs, then Apply")
|
||||
.help("Use the controller’s stereo pairs immediately")
|
||||
}
|
||||
Text(draft.mode == "Internal" ? "Internal mixes both decks through the main output. Pre-cueing can use channels 3–4 on the same four-channel sound card." : "External sends each deck to its own stereo pair. The software crossfader is bypassed; mix the outputs on your external mixer.").font(.callout).foregroundStyle(.secondary)
|
||||
if system.devices.isEmpty { Text("No audio outputs reported by macOS. Reconnect the interface and refresh.").foregroundStyle(.orange) }
|
||||
@@ -89,7 +99,7 @@ struct DJAudioDevicesPane: View {
|
||||
Text("\(device.outputChannels) out · \(device.inputChannels) in")
|
||||
if device.outputChannels >= 2 {
|
||||
Text(device.stereoPairs.map { "ch \($0+1)–\($0+2)" }.joined(separator:", ")).foregroundStyle(.secondary)
|
||||
} else { Text("Input only").foregroundStyle(.secondary) }
|
||||
} else { Text(device.outputChannels == 0 ? "Input only" : "Mono output").foregroundStyle(.secondary) }
|
||||
}
|
||||
}.font(.caption).padding(.vertical,3)
|
||||
}
|
||||
@@ -101,18 +111,14 @@ struct DJAudioDevicesPane: View {
|
||||
HStack {
|
||||
Button("Refresh Devices") { system.refreshDevices() }
|
||||
Spacer()
|
||||
Button("Revert") { draft = system.routing }.disabled(draft == system.routing)
|
||||
Button("Apply") { system.applyRouting(draft) }.buttonStyle(.borderedProminent).disabled(draft == system.routing || validation != nil)
|
||||
if validation != nil { Button("Revert invalid changes") { draft = system.routing } }
|
||||
Text("Changes apply immediately").font(.caption).foregroundStyle(.secondary)
|
||||
}
|
||||
}.onAppear {
|
||||
system.refreshDevices();draft = system.routing
|
||||
if draft == DJAudioRouting(),let recommended { draft = .controllerPreset(recommended,mode:"Internal") }
|
||||
}
|
||||
.onChange(of:draft.mode) { mode in
|
||||
if mode == "External",draft.deckA == DJAudioRoute(),draft.deckB == DJAudioRoute(),let recommended {
|
||||
draft.deckA = .init(uid:recommended.uid,firstChannel:0);draft.deckB = .init(uid:recommended.uid,firstChannel:2)
|
||||
if draft.cue.uid == recommended.uid { draft.cue = .init() }
|
||||
}
|
||||
.onChange(of:draft) { next in
|
||||
if next != system.routing,validation == nil { system.applyRouting(next) }
|
||||
}
|
||||
.task {
|
||||
while !Task.isCancelled {
|
||||
@@ -147,7 +153,7 @@ struct DJAudioChannelPicker: NSViewRepresentable {
|
||||
func makeNSView(context: Context) -> NSPopUpButton {
|
||||
let button = NSPopUpButton(frame:.zero,pullsDown:false)
|
||||
button.target = context.coordinator;button.action = #selector(Coordinator.changed(_:))
|
||||
button.setAccessibilityLabel(label);return button
|
||||
button.setAccessibilityLabel(label);button.identifier = NSUserInterfaceItemIdentifier(label);return button
|
||||
}
|
||||
func updateNSView(_ button: NSPopUpButton,context: Context) {
|
||||
context.coordinator.value = $value
|
||||
|
||||
Reference in New Issue
Block a user