removed unwanted bar now with waveforms, major updates and enhancements
This commit is contained in:
@@ -2074,14 +2074,14 @@ extension KJamsCloneTests {
|
||||
XCTAssertEqual(Array(leds.prefix(9)),[0x90,0,127,0x90,1,1,0x90,2,127])
|
||||
}
|
||||
@MainActor func testEQAndFilterDoubleClickActuallyResetKnobs() async throws {
|
||||
var values = [6.0,-6.0,0.75]
|
||||
let host = NSHostingView(rootView:HStack(spacing:0) { ForEach(0..<3,id:\.self) { i in DJKnob(label:["HIGH","LOW","FILTER"][i],value:Binding(get:{values[i]},set:{values[i] = $0}),range:i == 2 ? -1...1 : -12...12,reset:0,color:.cyan).frame(width:80,height:80) } }.frame(width:240,height:80))
|
||||
host.frame = NSRect(x:0,y:0,width:240,height:80)
|
||||
var values = [6.0,3.0,-6.0,0.75]
|
||||
let host = NSHostingView(rootView:HStack(spacing:0) { ForEach(0..<4,id:\.self) { i in DJKnob(label:["HIGH","MID","LOW","FILTER"][i],value:Binding(get:{values[i]},set:{values[i] = $0}),range:i == 3 ? -1...1 : -12...12,reset:0,color:.cyan).frame(width:80,height:80) } }.frame(width:320,height:80))
|
||||
host.frame = NSRect(x:0,y:0,width:320,height:80)
|
||||
let window = NSWindow(contentRect:host.frame,styleMask:[.borderless],backing:.buffered,defer:false);window.contentView = host
|
||||
let previous = NSApp.keyWindow;window.setFrameOrigin(NSPoint(x:-10000,y:-10000));window.orderFront(nil);window.makeKey()
|
||||
defer { window.orderOut(nil);window.contentView = nil;previous?.makeKey() }
|
||||
try await Task.sleep(nanoseconds:150_000_000);host.layoutSubtreeIfNeeded()
|
||||
for index in 0..<3 {
|
||||
for index in 0..<4 {
|
||||
for click in 1...2 {
|
||||
for type in [NSEvent.EventType.leftMouseDown,.leftMouseUp] {
|
||||
let event = try XCTUnwrap(NSEvent.mouseEvent(with:type,location:NSPoint(x:40+index*80,y:46),modifierFlags:[],timestamp:ProcessInfo.processInfo.systemUptime,windowNumber:window.windowNumber,context:nil,eventNumber:0,clickCount:click,pressure:type == .leftMouseDown ? 1 : 0));NSApp.sendEvent(event)
|
||||
@@ -2089,7 +2089,21 @@ extension KJamsCloneTests {
|
||||
}
|
||||
try await Task.sleep(nanoseconds:100_000_000)
|
||||
}
|
||||
XCTAssertEqual(values,[0,0,0])
|
||||
XCTAssertEqual(values,[0,0,0,0])
|
||||
func controls(_ view: NSView) -> [DJRotaryControl] { (view as? DJRotaryControl).map{[$0]} ?? view.subviews.flatMap{controls($0)} }
|
||||
let knobs = controls(host)
|
||||
XCTAssertEqual(knobs.count,4)
|
||||
for knob in knobs {
|
||||
let centre = knob.convert(NSPoint(x:knob.bounds.midX,y:14),to:nil)
|
||||
let down = try XCTUnwrap(NSEvent.mouseEvent(with:.leftMouseDown,location:centre,modifierFlags:[],timestamp:ProcessInfo.processInfo.systemUptime,windowNumber:window.windowNumber,context:nil,eventNumber:0,clickCount:1,pressure:1))
|
||||
knob.mouseDown(with:down)
|
||||
let drag = try XCTUnwrap(NSEvent.mouseEvent(with:.leftMouseDragged,location:NSPoint(x:centre.x,y:centre.y+12),modifierFlags:[],timestamp:ProcessInfo.processInfo.systemUptime,windowNumber:window.windowNumber,context:nil,eventNumber:0,clickCount:1,pressure:1))
|
||||
knob.mouseDragged(with:drag);XCTAssertNotEqual(knob.value,0)
|
||||
let label = knob.convert(NSPoint(x:knob.bounds.midX,y:35),to:nil)
|
||||
let doubleClick = try XCTUnwrap(NSEvent.mouseEvent(with:.leftMouseDown,location:label,modifierFlags:[],timestamp:ProcessInfo.processInfo.systemUptime,windowNumber:window.windowNumber,context:nil,eventNumber:0,clickCount:2,pressure:1))
|
||||
knob.mouseDown(with:doubleClick);XCTAssertEqual(knob.value,0)
|
||||
}
|
||||
XCTAssertEqual(values,[0,0,0,0],"Reset on the label also updates each audio parameter after a drag")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2362,9 +2376,7 @@ extension KJamsCloneTests {
|
||||
let libraryFrame = libraryScroll.convert(libraryScroll.bounds,to:host)
|
||||
if host.isFlipped { XCTAssertGreaterThan(libraryFrame.maxY,host.bounds.maxY-50,"The library fills the bottom of the workspace") }
|
||||
else { XCTAssertLessThan(libraryFrame.minY,host.bounds.minY+50,"The library fills the bottom of the workspace") }
|
||||
if let rep = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:rep);try XCTUnwrap(rep.representation(using:.png,properties:[:])).write(to:URL(fileURLWithPath:"/private/tmp/kjmix-xml-mappings/dj-tab.png")) }
|
||||
try await selectTab(0)
|
||||
if let rep = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:rep);try XCTUnwrap(rep.representation(using:.png,properties:[:])).write(to:URL(fileURLWithPath:"/private/tmp/kjmix-xml-mappings/karaoke-tab.png")) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3234,6 +3246,16 @@ extension KJamsCloneTests {
|
||||
let window = NSWindow(contentRect:view.frame,styleMask:[.borderless],backing:.buffered,defer:false)
|
||||
window.contentView = view;window.appearance = NSAppearance(named:.darkAqua);window.setFrameOrigin(NSPoint(x:-10000,y:-10000));window.orderFront(nil)
|
||||
try await Task.sleep(nanoseconds:250_000_000);view.layoutSubtreeIfNeeded()
|
||||
if size.width == 1320 {
|
||||
system.a.player.filter = 0.63;system.b.player.filter = -0.31
|
||||
try await Task.sleep(nanoseconds:60_000_000);view.layoutSubtreeIfNeeded()
|
||||
func knobs(_ parent: NSView) -> [DJRotaryControl] { (parent as? DJRotaryControl).map{[$0]} ?? parent.subviews.flatMap{knobs($0)} }
|
||||
let filters = knobs(view).filter{$0.label == "FILTER"}
|
||||
XCTAssertEqual(filters.count,2)
|
||||
XCTAssertTrue(filters.contains{abs($0.value-0.63) < 0.001});XCTAssertTrue(filters.contains{abs($0.value+0.31) < 0.001},"External audio-model changes update both mixer strips")
|
||||
for filter in filters { filter.resetToDefault() }
|
||||
XCTAssertEqual(system.a.player.filter,0);XCTAssertEqual(system.b.player.filter,0)
|
||||
}
|
||||
let rep = try XCTUnwrap(view.bitmapImageRepForCachingDisplay(in:view.bounds));view.cacheDisplay(in:view.bounds,to:rep)
|
||||
let png = try XCTUnwrap(rep.representation(using:.png,properties:[:]))
|
||||
let path = root.appendingPathComponent("DJ-Studio-\(Int(size.width)).png");try png.write(to:path)
|
||||
@@ -3246,3 +3268,29 @@ extension KJamsCloneTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension KJamsCloneTests {
|
||||
@MainActor func testClearingDeckMarkersPreservesLoadedPlayingAudio() async throws {
|
||||
let root = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
defer { try? FileManager.default.removeItem(at:root) }
|
||||
let fixture = try XCTUnwrap(Bundle(for:Self.self).resourceURL?.appendingPathComponent("Fixtures/Demo.wav"))
|
||||
let player = Player(waveformCacheDirectory:root,persistsMix:false)
|
||||
defer { player.stop() };player.autoFade = false
|
||||
try player.load(Song(id:7,title:"Markers",audio:fixture.path,cdg:nil,rating:0,plays:0),startPlaying:false)
|
||||
player.setCue(at:0.4)
|
||||
for index in 0..<4 { player.seek(0.2+Double(index)*0.1);player.hotCue(index) }
|
||||
XCTAssertTrue(player.hotCues.allSatisfy{$0 != nil})
|
||||
player.hotCue(2,clear:true);XCTAssertNil(player.hotCues[2]);XCTAssertNotNil(player.hotCues[0])
|
||||
player.defineLoop(start:0.2,end:0.5)
|
||||
for _ in 0..<100 where !player.nativeLoopActive { try await Task.sleep(nanoseconds:5_000_000) }
|
||||
player.seek(0.25);player.toggle();try await Task.sleep(nanoseconds:80_000_000)
|
||||
let position = player.displayTime
|
||||
player.clearDeckMarkers()
|
||||
XCTAssertEqual(player.currentSongID,7);XCTAssertTrue(player.playing);XCTAssertTrue(player.audioPlaybackStarted)
|
||||
XCTAssertTrue(player.hotCues.allSatisfy{$0 == nil});XCTAssertEqual(player.cuePosition,0)
|
||||
XCTAssertNil(player.loopIn);XCTAssertNil(player.loopOut);XCTAssertFalse(player.loopEnabled)
|
||||
XCTAssertEqual(player.displayTime,position,accuracy:0.04,"Clearing markers must not jump back to the start")
|
||||
try await Task.sleep(nanoseconds:160_000_000)
|
||||
XCTAssertGreaterThan(player.displayTime,position+0.08)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user