better state reporting
This commit is contained in:
@@ -392,7 +392,7 @@
|
||||
|
||||
(let ((m-id (hash-ref h 'at-music-id)))
|
||||
(unless (and (null? force) (or (eq? m-id #f) (= m-id 0)))
|
||||
(cb (list 'state h))))
|
||||
(cb (list 'state (list h player-state)))))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+5
-4
@@ -130,7 +130,7 @@
|
||||
(cmd-put (cons cmd args)) (ret-get))))
|
||||
|
||||
(let* ((handle #f)
|
||||
(cb-state* (λ (st) (cb-state handle st)))
|
||||
(cb-state* (λ (st st-hash) (cb-state handle st st-hash)))
|
||||
(cb-eof* (λ () (cb-eof-stream handle))))
|
||||
(set! handle (make-audio-play #t
|
||||
cb-state* cb-eof*
|
||||
@@ -144,10 +144,11 @@
|
||||
(let loop ()
|
||||
(if (audio-play-valid? handle)
|
||||
(let ((e (evt-get 500)))
|
||||
(cond ((eq? e #f) (loop))
|
||||
(cond ((eq? e #f) (void))
|
||||
((is-event? e 'state)
|
||||
(set-audio-play-state! handle (evt-data e))
|
||||
(cb-state* (evt-data e)))
|
||||
(let ((data (evt-data e)))
|
||||
(set-audio-play-state! handle (car data))
|
||||
(cb-state* (cadr data) (car data))))
|
||||
((is-event? e 'audio-done) (cb-eof*))
|
||||
((is-event? e 'exception)
|
||||
(err-sound "audio-player: exception event: ~a" e))
|
||||
|
||||
@@ -36,11 +36,54 @@ all other procedures in this module.
|
||||
The @racket[cb-state] callback is called as:
|
||||
|
||||
@racketblock[
|
||||
(cb-state player state-hash)]
|
||||
(cb-state player current-player-state state-hash)]
|
||||
|
||||
where @racket[player] is the player handle and @racket[state-hash] is the most
|
||||
recent state snapshot received from the worker side. The callback is called
|
||||
from the event thread created by @racket[make-audio-player].
|
||||
where @racket[player] is the player handle,
|
||||
@racket[current-player-state] is the logical player state reported by the
|
||||
worker, and @racket[state-hash] is the most recent state snapshot received from
|
||||
the worker side. The callback is called from the event thread created by
|
||||
@racket[make-audio-player].
|
||||
|
||||
The worker-side player state is one of the following symbols:
|
||||
|
||||
@itemlist[
|
||||
#:style 'compact
|
||||
|
||||
@item{@racket['stopped] -- no stream is currently playing. This is the
|
||||
initial state of the placed player. The player also enters this state after
|
||||
@racket[audio-stop!] or after the decoder has reached the end of the stream
|
||||
and the libao output queue has drained.}
|
||||
|
||||
@item{@racket['playing] -- a stream is active. The decoder may still be
|
||||
reading from the input file, or the decoder may already have finished while
|
||||
libao is still playing queued PCM samples.}
|
||||
|
||||
@item{@racket['paused] -- playback is paused. The current stream is retained
|
||||
and the libao output side is paused. Resuming playback moves the player back
|
||||
to @racket['playing].}
|
||||
|
||||
@item{@racket['quit] -- the placed player has been asked to terminate. This
|
||||
is the terminal state of the worker.}
|
||||
]
|
||||
|
||||
The wrapper around the placed player may also report these states through
|
||||
@racket[audio-state]:
|
||||
|
||||
@itemlist[
|
||||
#:style 'compact
|
||||
|
||||
@item{@racket['initialized] -- the audio handle has been created, but no
|
||||
worker-side state snapshot has been received yet.}
|
||||
|
||||
@item{@racket['invalid] -- the audio handle is no longer valid. This happens
|
||||
after @racket[audio-quit!] or when the underlying place or thread has stopped.}
|
||||
]
|
||||
|
||||
The @racket[state-hash] contains the detailed playback state reported by the
|
||||
worker. It includes values such as the current playback position, stream
|
||||
duration, buffer status, music id, and libao handle validity. Code that only
|
||||
needs the logical playback state should use @racket[current-player-state]
|
||||
instead of extracting it from the hash.
|
||||
|
||||
The @racket[cb-eof-stream] callback is called as:
|
||||
|
||||
@@ -52,6 +95,8 @@ that the decoder has finished queueing the stream. The audio device may still
|
||||
have buffered samples to play, and the logical player state may move to
|
||||
@racket['stopped] slightly later when the output queue has drained.
|
||||
|
||||
End-of-stream is not represented as a separate player state.
|
||||
|
||||
When @racket[use-place] is true, @racket[make-audio-player] starts
|
||||
@racket[placed-player] with @racket[dynamic-place] and communicates with it
|
||||
through place channels. When @racket[use-place] is false, the same command loop
|
||||
@@ -65,6 +110,7 @@ other active threads in the main VM. Those delays can otherwise be heard as
|
||||
clicks, gaps, or stuttering playback. Thread mode is useful for debugging the
|
||||
protocol and callbacks, but it is not the preferred mode for robust playback.}
|
||||
|
||||
|
||||
@defproc[(audio-play? [v any/c]) boolean?]{
|
||||
Returns @racket[#t] when @racket[v] is a currently valid audio player handle.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user