You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Not really sure where this problem comes from but I'll try my best to explain.
I've got a basic loop that idles in blocking mode waiting for Subsystem::Player events, matches Status.state and sets the cover on song change, or unsets it if stopped. It all goes well with other types of files, but if I start playing a DSF file I have a surge of player events and Status.state is always State::Stop. Meanwhile CPU usage goes sky high while looping through those events. Is this possibly an issue with MPD itself? How can I provide more info? Any way to clear the idle events queue?
Meanwhile mpc correctly reports state as playing
Edit: I asked if I can clear the events queue because even if I change the song to a known working one, say FLAC, MP3, whatever, I continue getting the accumulated events and state continues being matched to State::Stop.
Investigating why the call to wait() doesn't block when playing a DSD file I found out this.
The first two calls to client.wait(&[mpd::Subsystem::Player]) result in immediate Ok([]). Why is the list empty and not Ok([Player]) as expected?
After those two I start getting Err(Io(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })), so yeah, that's why no blocking. Still need to figure out why the connection breaks down... If I reinitialize the client at the beginning of each loop iteration instead of outside the loop wait() returns immediate Ok([]) at each call.
Can you test it yourself? Play some DSD and run the following:
use mpd::Idle;fnmain(){letmut mpc = mpd::Client::connect("127.0.0.1:6600").unwrap();for _ in0..5{ifletErr(e) = mpc.status(){eprintln!("status error: {:?}", e);}// Do something
std::thread::sleep(std::time::Duration::from_millis(100));let result = mpc.wait(&[mpd::Subsystem::Player]);eprintln!("idle result: {:?}", result);}}
Basically FromStr should be orthogonal to ToString in AudioFormat.cxx. To achieve this without loss of information I've introduced a small enum -- SampleFormat, have a look at the last file in the gist: test.rs. I've used it for testing. The implementation of FromStr there is still not completely orthogonal though. It returns an error in case of SampleFormat::UNDEFINED but doesn't check if rate or chans equal zero, which they shouldn't.
Note that floating point PCM signal is defined with 32 bit resolution, not zero. Zero is defined as SampleFormat::UNDEFINED, so an error. You can verify that in the definition of sample_format_size() in SampleFormat.hxx.
Activity
zhelezov commentedon May 11, 2019
My bad, I was using
unwrap_or_defaultto get theStatusso I was masking the actual error:Parse(BadRate(ParseIntError { kind: InvalidDigit }))So you can ignore the part that concerns matching against
Status.stateThe result from probing MPD directly:
I'll have a look at the status parser later, but the
audio: dsd64:2field seems to be the culprit.And still I don't get it, why the next call to
wait()doesn't block?[-]Status::Stop when _playing_ DSF files[/-][+]Error getting status when playing DSD files[/+][-]Error getting status when playing DSD files[/-][+]Error parsing status when playing DSD files[/+]zhelezov commentedon May 11, 2019
Investigating why the call to
wait()doesn't block when playing a DSD file I found out this.The first two calls to
client.wait(&[mpd::Subsystem::Player])result in immediateOk([]). Why is the list empty and notOk([Player])as expected?After those two I start getting
Err(Io(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })), so yeah, that's why no blocking. Still need to figure out why the connection breaks down... If I reinitialize the client at the beginning of each loop iteration instead of outside the loopwait()returns immediateOk([])at each call.Can you test it yourself? Play some DSD and run the following:
I get:
zhelezov commentedon May 12, 2019
Hi, I had a look at the parser and came up with the following which works for me:
I'm new to Rust so I've no idea if it's idiomatic or silly, or whatever, but that's the gist and it works. I found the info in the MPD user manual, it was missing from the protocol specs, here:
https://www.musicpd.org/doc/html/user.html#configuring-audio-outputs
Anyway, I've still no clue why the connection breaks down on parse error, haven't looked at it. Any idea?
zhelezov commentedon May 13, 2019
I've found these relevant bits in the MPD code base and I've put them together in a gist so I stop cluttering this feed with overly long snippets: https://gist.github.com/zhelezov/585e0dd20cce521f16cd46da00fa3f68
Basically
FromStrshould be orthogonal toToStringinAudioFormat.cxx. To achieve this without loss of information I've introduced a small enum --SampleFormat, have a look at the last file in the gist:test.rs. I've used it for testing. The implementation ofFromStrthere is still not completely orthogonal though. It returns an error in case ofSampleFormat::UNDEFINEDbut doesn't check ifrateorchansequal zero, which they shouldn't.Note that floating point PCM signal is defined with 32 bit resolution, not zero. Zero is defined as
SampleFormat::UNDEFINED, so an error. You can verify that in the definition ofsample_format_size()inSampleFormat.hxx.