Closed szgambol closed 2 years ago
Does the DAC show that it is receiving DSD input? If so that means at least the DoP markers are being correctly transmitted.
As an aside, you might consider waiting for the sample rate change to take effect (using a property listener) before calling player.play
, although I don't think that's related to your issue.
Yes, the DAC can display DSD64 when playing.
I try to set delay ( 2、5、10 seconds ) calling player.play after set sample rate, it nothing change, still noise in the sound.
And I used another DAC OPPO Sonica DAC to test, it ok (both on DSD64 and DSD128 test file), no noise in the sound, DAC display DSD on 2.822 MHz / DSD on 5.644 MHz.
I noticed if set delay ( 2 seconds ) after set sample rate, play DSD128 file, DAC( McIntosh C47 ) also can display DSD128, if not, will display 352.8kHz
Test code below:
if let device = AudioObject.make(player.outputDeviceID) as? AudioDevice {
try device.setSampleRate(sampleRate)
}
var bFlag = true
let date_old = Date()
let tmDelay = 2
while bFlag {
let elapsed = Date().timeIntervalSince(date_old)
let duration = Int(elapsed)
bFlag = duration < tmDelay
usleep(1000 * 500) // 0.5 secodns
}
if let decoder = try item.decoder(enableDoP: enableDoP) {
try player.play(decoder)
}
Since it's working with the OPPO DAC I assume the problem lies with the non-deterministic amount of time it is taking for the McIntosh to change sample rates. What happens when using a property listener and not calling play
until the sample rate change is complete?
Thank your suggestion.
I am so sorry that I am a newer for swift, actually I don’t know how to write property listener for device sample rate change in this project now.
I think your mean is , I need to check device sample rate, ensure call player.play must be after change is completed, so I write a timer instead property listener ( I'm not sure if it's the right way ), run this code, it seem device always change sample rate correct, because log output like below, but noise did not disappear :
2021-11-01 14:14:35.332241+0800 SimplePlayer[87590:1506374] [AudioObject] Setting device 0x3a sample rate to 176400.00 Hz
-------------------------------------------------
176400.0 -> device.actualSampleRate : 176400.0 device.sampleRate : 176400.0
Sample rate is changed!
That is my test code:
func play(item: PlaylistItem) {
do {
var enableDoP = false
var sampleRate : Double = 48 * 1000
if let audioFile = try? AudioFile(readingPropertiesAndMetadataFrom: item.url) {
let bitPerChannel = audioFile.properties.bitsPerChannel
sampleRate = audioFile.properties.sampleRate ?? sampleRate
enableDoP = bitPerChannel == 1
if (enableDoP) {
sampleRate = sampleRate / 16
}
if let device = AudioObject.make(player.outputDeviceID) as? AudioDevice {
try device.setSampleRate(sampleRate)
}
let context = [sampleRate, enableDoP, item] as [Any]
Timer.scheduledTimer(
timeInterval : 1.0,
target: self,
selector: #selector(checkDevice),
userInfo: context,
repeats: true)
}
}
catch let error {
NSApp.presentError(error)
}
}
checkDevice function
var runCount = 5
@objc func checkDevice(timer: Timer)
{
guard let context = timer.userInfo as? [Any] else { return }
let setting_sampleRate :Double = context[0] as! Double
let enableDoP :Bool = context[1] as! Bool
let item :PlaylistItem = context[2] as! PlaylistItem
do {
if let device = AudioObject.make(player.outputDeviceID) as? AudioDevice {
let actualSampleRate : Double = try device.actualSampleRate()
let sampleRate : Double = try device.actualSampleRate()
print("-------------------------------------------------")
print(setting_sampleRate," -> device.actualSampleRate : ", actualSampleRate, "device.sampleRate : ", sampleRate)
if fabs(setting_sampleRate - actualSampleRate) < Double.ulpOfOne {
print("Sample rate is changed!")
timer.invalidate()
runCount = 5
if let decoder = try item.decoder(enableDoP: enableDoP) {
try player.play(decoder)
}
}
}
}
catch let error {
print(error)
timer.invalidate()
runCount = 5
}
runCount -= 1
if runCount == 0 {
timer.invalidate()
runCount = 5
}
}
Hi,
I can write property listener now, and when I test nominalSampleRate property is work, but actualSampleRate no work ( listener never be trigger ), when I use nominalSampleRate property for trigger to call player.play still noise.
It seem can't detect actualSampleRate change from my DAC (both OPPO and McIntosh).
do I correct about property listener ?
I edited updateDeviceMenu() func, add code below:
if isActiveDevice {
devicePopUpButton.select(deviceMenuItem)
/// make property listener for nominalSampleRate
/// actualSampleRate, nominalSampleRate
if let device = AudioObject.make(currentOutputDeviceID) as? AudioDevice {
/// TODO : need to unregister listener when device change
/// TODO : when sample rate not change will not to play
try device.whenSelectorChanges(AudioObjectSelector.nominalSampleRate, perform: {_ in
DispatchQueue.main.async {
self.onSampleRateChanged()
}
})
}
}
function onSampleRateChanged:
func onSampleRateChanged() {
do {
let item : PlaylistItem? = self.currentItem
let enableDoP : Bool = self.currentEnableDop
if let decoder = try item!.decoder(enableDoP: enableDoP) {
try player.play(decoder)
}
print("nominalSampleRate is changed")
} catch let error {
NSApp.presentError(error)
}
}
code in the function func play(item: PlaylistItem)
self.currentItem = item
self.currentEnableDop = enableDoP
if let device = AudioObject.make(player.outputDeviceID) as? AudioDevice {
try device.setSampleRate(sampleRate)
}
I assume the problem happens on more than one file? Are you able to test with both a .dsf and .dsdiff file?
Yes, I test another DSD file that is .dff format, same thing happended.
I'm not quite sure yet what the problem could be so I don't have any great suggestions to diagnose the issue. Does ensuring the player is stopped before changing the sample rate have any effect?
Also, does the McIntosh DAC use the CoreAudio drivers?
I aways click stop button first and then select new DSD file, so I think the player stoped.
McIntosh C-47 only supply ASIO driver for Win, but say support DoP on OS X without driver.
Thank you for your replay. I'll check things out again if there are any updates.
Hi,
I think maybe I found the problem about the noise.
When I use MIDI tools, my DAC MC-47 has three options under 176.4 kHz,
If I select 2ch 24-bit Integer and 2ch 32-bit Integer, the noise will be gone, and 2ch 16-bit Integer the noise will be back.
And I try to find the way to select correct options with Core Audio API, it seem no support, do you have any suggests ?
Those formats are properties of the AudioStream objects in the output scope of the AudioDevice. A stream has a virtual and physical format. You can inspect them using the AudioDevice
and AudioStream
classes.
You can try searching kAudioDevicePropertyStreams
, kAudioStreamPropertyVirtualFormat
, or kAudioStreamPropertyAvailableVirtualFormats
for more information.
Yes, change physical format with AudioStream can set the device to 2ch 24Bit 176.4kHz in my DAC, thank you for you help !
I use SimplePlayer-macOS test dsd audio file ( DSD64 ) in DoP mode, referred Issues#185, set the device sample rate before play, but in my situation , I heard a lot noise in the sound, that is my test code below:
Hope get some suggestion, thank very much.
BTW:
My DAC is McIntosh C47, use Other APP (like Audirvana Plus) to play in DoP mode is ok.