DSD over DoP for Multi-channel playback

Started by soundgals,

soundgals

Using BASS_DSD with the DoP flag: BASS_DSD_DOP, I am able to play DSD over PCM stereo through BASS. I can't get this to work for multi-channel files though. Multi-channel works fine for PCM or for DSD when I remove the BASS_DSD_DOP flag, so it defaults to PCM playback.

Can you confirm if this is a limitation of BASS when it comes to DSD multi-channel over DoP? If so, are there any plans to implement this?

If not, I may be doing something wrong on my side.

Thanks in advance for your help on this.

Geoff

Ian @ un4seen

I haven't tried it myself but I believe multichannel DoP should be supported. What problem are you having with it? If BASS_DSD_StreamCreateFile is failing, please check the error code with BASS_ErrorGetCode. If it just doesn't sound right (eg. silence) on your DSD device, check that your soundcard's output format matches the DoP stream's format (which you can get from BASS_ChannelGetInfo) so that there's no resampling required (which would corrupt the DSD data). If the problem persists, also confirm what platform you're running this on.

soundgals

Quote from: Ian @ un4seenI haven't tried it myself but I believe multichannel DoP should be supported. What problem are you having with it? If BASS_DSD_StreamCreateFile is failing, please check the error code with BASS_ErrorGetCode. If it just doesn't sound right (eg. silence) on your DSD device, check that your soundcard's output format matches the DoP stream's format (which you can get from BASS_ChannelGetInfo) so that there's no resampling required (which would corrupt the DSD data). If the problem persists, also confirm what platform you're running this on.

Thanks Ian. The platform is MacOS and I'm using the CBass wrapper for BASS. The BASS_DSD_StreamCreateFile is succeeding I believe. because I hear noise(static). I set the devices sample rate and channels to match the incoming data using core audio and if the sample rate of the stream doesn't match the BASS device I re-init BASS with the correct sample rate. Oddly, I don't hear noise on the front L + R channels; just on the other channels of the 5.1 set-up. The output device is set via audio-midi player to output to classic 5.1 speaker mapping.

Ian @ un4seen

If you call BASS_ChannelGetInfo on the DoP stream and BASS_GetInfo, do the BASS_CHANNELINFO freq/chans values match the BASS_INFO freq/speakers values?

Also, is the DSD file playing correctly with other software on the same system?

soundgals

#4
Quote from: Ian @ un4seenIf you call BASS_ChannelGetInfo on the DoP stream and BASS_GetInfo, do the BASS_CHANNELINFO freq/chans values match the BASS_INFO freq/speakers values?

Also, is the DSD file playing correctly with other software on the same system?
I think you may have hit on the problem here. The frequencies match; but the channels don't. The source has 6 channels; but the device has 8 channels. BASS_INFO shows 8 "speakers".

... but then I ask myself, why is this not a problem with PCM multi-channel playback with 6 channels?

To get multi-channel audio to play through this DAC it needs to be set as 8 channels in Audio-Midi set-up (I do this programatically through core audio).

Other software (e.g. HQPlayer) is able to play these 6 channels over DOP as DSD without a problem.


In Audio Midi set-up (as you probably already know) you set your actual number of speakers and the channel mapping within the "Configure speakers..." panel. The physical device that BASS "sees" will always have 8 channels though, for such a device. So they'd only match if the source file itself had 8 channels.

Ian @ un4seen

I think the soundcard output having more channels than the DoP stream should be fine. Does your DSD device indicate when it detects DoP data, and if so, does it do so in this case?

To confirm whether the BASS output is valid DoP data, you could try writing it to a WAV file, like this:

devstream = BASS_StreamCreate(0, 0, 0, STREAMPROC_DEVICE, 0); // get device stream
BASS_Encode_Start(devstream, "output.wav", BASS_ENCODE_PCM | BASS_ENCODE_FP_24BIT, 0, 0); // set 24-bit WAV writer on it
// play DoP stream here
BASS_Encode_Stop(devstream); // stop WAV writer

And then check for DSD markers in the WAV file's data, as described here:

    https://dsd-guide.com/dop-open-standard

It probably won't affect this but you could also try using the latest BASS build available here:

   www.un4seen.com/stuff/bass-osx.zip

soundgals

Thanks for the tips Ian.

The device should indicate 2.8xxx MHZ as it does for Stereo DOP; but when trying to send multi-channel via DoP it's showing 176.4 khz and I get the static noise.

I'll try writing to the WAV file as you suggested and updating to the latest BASS just in case.

soundgals

With a little help from AI, I create some Swift functions to check for DoP markers in a multi-channel DSD file using the DoP flag in BASS. The results were as follows...
--- DSD Playback Diagnostics ---
Channel status: 0
Channel position: 18446744073709551615 bytes
Data available in buffer: 4294967295 bytes
Could not read data from channel, error: 5
Testing for DoP markers on device 129...
Device stream created successfully
Capturing from device: 176400Hz, 8 channels
Analyzing audio output for DoP markers...
--- DoP Analysis Results ---
Total bytes captured: 0
Successful capture attempts: 0
Total DoP markers found: 0

... As I mentioned before the same source plays just fine as 176400 PCM with the DoP flag removed. DSD Stereo also plays just fine with the DoP flag.

So I've come to the conclusion that, at least in the CBass wrapper implementation of BASS I'm using, DoP isn't supported for multi-channel.

It's not a big deal for me; but I would like my app to be able to support this if possible. I'll try up-grading the CBass Swift package, just in case it makes a difference.

If you want me to share any of the diagnostic Swift code with you, of course I can do that.

Ian @ un4seen

If you upload the BASS output WAV file (from the code in my last post), I'll have a look at it. You can upload it here:

    ftp://ftp.un4seen.com/incoming/

A few seconds of playback will suffice (you don't need to play the entire DSD file).

soundgals

Thanks Ian.

I did attempt this; but I always got error 33 when trying to start the encoder.

Below is the Swift code I attempted to use to get this working. Perhaps you can spot where I might be going wrong.

stream = BASS_DSD_StreamCreateURL(theURL, 0, DWORD(BASS_DSD_DOP | BASS_SAMPLE_FLOAT | BASS_STREAM_STATUS), nil, nil, DWORD(BASS_CONFIG_DSD_FREQ))
            if stream == 0{
                let error = BASS_ErrorGetCode()
                print("Can't create stream", error)
            }
           
            var channelInfo = BASS_CHANNELINFO()
            BASS_ChannelGetInfo(stream, &channelInfo)
            // try to change the device's rate
            print("Channels: \(channelInfo.chans)")
            if (info.freq != channelInfo.freq){ // the rates don't match
                BASS_Init(device, channelInfo.freq, DWORD(BASS_DEVICE_FREQ | BASS_DEVICE_REINIT), nil, nil)
            }
            var devstream: HSTREAM = 0

            // Define the STREAMPROC function type to match what BASS expects
            typealias STREAMPROC = @convention(c) (HSTREAM, UnsafeMutableRawPointer?, DWORD, UnsafeMutableRawPointer?) -> DWORD

            // Create STREAMPROC_DEVICE by casting the special value -2
            let STREAMPROC_DEVICE = unsafeBitCast(-2, to: STREAMPROC?.self)

            // Create the device stream
            devstream = BASS_StreamCreate(0, 0, 0, STREAMPROC_DEVICE, nil)

            if devstream == 0{
                let error = BASS_ErrorGetCode()
                print("Can't create stream", error)
            }
            let musicUrl = FileManager.default.urls(for: .musicDirectory, in: .userDomainMask).first!
            // BASS requires the "file://" prefix to be removed from the url in string format
            let destinationUrl = musicUrl.appendingPathComponent("output.wav").absoluteString.replacingOccurrences(of: "file://", with: "")
            BASS_ChannelPlay(stream, 1)
            let encoder = BASS_Encode_Start(devstream, destinationUrl,  DWORD(BASS_ENCODE_PCM | BASS_ENCODE_FP_24BIT | BASS_ENCODE_AUTOFREE), nil, nil)
           
            if encoder == 0{
                let error = BASS_ErrorGetCode()
                print("Can't start the encoder", error)
            }
            BASS_Encode_Stop(devstream)

Ian @ un4seen

Error code 33 is BASS_ERROR_CREATE, which means that BASS_Encode_Start was unable to create the file, possibly because the app doesn't have permission to write in the requested path. You could try "/tmp/output.wav" instead.

Note the BASS_Encode_Stop call should come some time (eg. a few seconds) after you've started playing the DSD file.

soundgals

I've created an 8 second file. Tried to connect to your ftp as a guest; but it wouldn't allow me to upload the file there. It's 32.1mb.
Please advise how I can get it to you. Thanks.

Ian @ un4seen

That file does appear to contain DoP data in 5 channels (L+R+C+RL+RR) and 3 empty channels, so I guess the DSD file you were playing has 5 channels? One issue I notice is that the stream is being ramped-in, which won't work properly on DoP data and should be disabled. You can disable it via the BASS_ATTRIB_NORAMP option:

BASS_ChannelSetAttribute(stream, BASS_ATTRIB_NORAMP, 1); // disable ramping

If your DSD device still doesn't detect DoP data, please post the soundcard's settings in the Audio MIDI Setup, including the "Configure Speakers" settings. Make sure all channel volumes are at 1.0.

soundgals

Quote from: Ian @ un4seenThat file does appear to contain DoP data in 5 channels (L+R+C+RL+RR) and 3 empty channels, so I guess the DSD file you were playing has 5 channels? One issue I notice is that the stream is being ramped-in, which won't work properly on DoP data and should be disabled. You can disable it via the BASS_ATTRIB_NORAMP option:

Indeed it was a 5 channel file, in that case. I will try the BASS_ATTRIB_NORAMP option. I guess I should be using that for all DoP data including stereo? The stereo played fine though.

Quote from: Ian @ un4seenBASS_ChannelSetAttribute(stream, BASS_ATTRIB_NORAMP, 1); // disable ramping

If your DSD device still doesn't detect DoP data, please post the soundcard's settings in the Audio MIDI Setup, including the "Configure Speakers" settings. Make sure all channel volumes are at 1.0.
]
I'll let you know, one way or the other and if it still doesn't work, I'll send you the Audio MIDI Setup data.

soundgals

Unfortunately this made no difference. So I'm attaching screenshots of Audio-Midi Set-up
Audio-Midi set-up

Ian @ un4seen

Quote from: soundgalsI will try the BASS_ATTRIB_NORAMP option. I guess I should be using that for all DoP data including stereo? The stereo played fine though.

Ramping-in would corrupt the first few milliseconds of DoP data, but I would expect it to play fine after that. Still a good idea to disable ramping on DoP streams (I'll have BASSDSD do that automatically in the next release).

Quote from: soundgalsUnfortunately this made no difference. So I'm attaching screenshots of Audio-Midi Set-up
Audio-Midi set-up

All of the channel volume sliders there should be set to "1,0". If doing that doesn't fix the problem, I think I'll have to send you a debug BASS version to get more info.

soundgals

Quote from: Ian @ un4seenAll of the channel volume sliders there should be set to "1,0". If doing that doesn't fix the problem, I think I'll have to send you a debug BASS version to get more info.
Thanks Ian. The only reason some of those sliders were set to minimum values was to avoid the noise that was being generated. I could see if the multi-channel DoP DSD was working by checking the sample rate showing on the front of the DAC. If it shows 176.4 I'm not getting DSD over DoP. For that it would have to read the correct DSD sample rate, as it does for stereo.

Ian @ un4seen

OK, so just to be clear, the problem does still happen when all volume sliders are set to 1.0?

Is stereo DoP playback still working when the soundcard is set to 8 channels? Or do you need to set the soundcard to stereo first?

soundgals

Quote from: Ian @ un4seenOK, so just to be clear, the problem does still happen when all volume sliders are set to 1.0?

Is stereo DoP playback still working when the soundcard is set to 8 channels? Or do you need to set the soundcard to stereo first?

Yes, the problem does still happen when I set all volume sliders to 1.0. I made a separate test for this.

DoP playback only works for stereo when I first set the device to 2 channels.