* [RFC] player: "cue prev" reliably hits previous cue breakpoint
@ 2016-04-11 2:27 Eric Wong
2016-04-24 2:45 ` [PATCH] player: extra "cue" seeking functionality Eric Wong
0 siblings, 1 reply; 2+ messages in thread
From: Eric Wong @ 2016-04-11 2:27 UTC (permalink / raw)
To: dtas-all
Seeking around a track should not be done relative to
a previous seek, but should rather be analogous to the
"tl prev" command to skip around the tracklist.
I'm not sure what drugs I was on when I originally wrote
this original version, but I'm fairly certain this is a
bugfix and not intentional behavior.
---
Thoughts? I'm _pretty_ sure this is the right thing to do;
will think about it for a bit...
lib/dtas/player/client_handler.rb | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/dtas/player/client_handler.rb b/lib/dtas/player/client_handler.rb
index 7b33967..8a15974 100644
--- a/lib/dtas/player/client_handler.rb
+++ b/lib/dtas/player/client_handler.rb
@@ -745,9 +745,9 @@ def __bp_prev_next(io, msg, cur, bp)
return io.emit("INVALID TYPE")
end
fmt = cur.format
+ ds = __current_decoded_samples
case msg[0]
when "next"
- ds = __current_decoded_samples
bp.each do |ci|
next if ci.offset_samples(fmt) < ds
seek_internal(cur, ci.offset)
@@ -756,11 +756,15 @@ def __bp_prev_next(io, msg, cur, bp)
# go to the next (real) track if not found
__current_drop
when "prev"
- os = cur.offset_samples # where we currently started
+ prev = nil
bp.reverse_each do |ci|
- next if ci.offset_samples(fmt) >= os
- seek_internal(cur, ci.offset)
- return io.emit("OK")
+ if prev.nil?
+ next if ci.offset_samples(fmt) >= ds
+ prev = ci
+ else
+ seek_internal(cur, ci.offset)
+ return io.emit("OK")
+ end
end
# offset may be nil/zero if we couldn't find a previous breakpoint
seek_internal(cur, '0')
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] player: extra "cue" seeking functionality
2016-04-11 2:27 [RFC] player: "cue prev" reliably hits previous cue breakpoint Eric Wong
@ 2016-04-24 2:45 ` Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2016-04-24 2:45 UTC (permalink / raw)
To: dtas-all
These commands allow easier jumping within a track marked by
embedded CUE sheets. I've found them helpful for tracking out
large recordings of multiple tracks (e.g. vinyl transfers or
live concert recordings).
---
This is a followup-to commit 285155328f72
https://80x24.org/dtas-all/20160411022743.GA22090@dcvr.yhbt.net/
Documentation/dtas-player_protocol.pod | 19 ++++++++--
lib/dtas/player/client_handler.rb | 66 ++++++++++++++++++++++++++++++----
2 files changed, 77 insertions(+), 8 deletions(-)
diff --git a/Documentation/dtas-player_protocol.pod b/Documentation/dtas-player_protocol.pod
index d0dd25e..be9f4ef 100644
--- a/Documentation/dtas-player_protocol.pod
+++ b/Documentation/dtas-player_protocol.pod
@@ -96,7 +96,7 @@ Commands here should be alphabetized according to `LC_ALL=C sort'
PENDING: this may be renamed to "queue clear" or "queue-clear"
-=item cue - display the index/offsets of the embedded cue sheet
+=item cue - display the index/offsets of the embedded CUE sheet
=item cue next - skip to the next cue sheet offset
@@ -109,11 +109,26 @@ This may just seek to the beginning
if there is no embedded cue sheet or if we are playing the first
(embedded) track.
-=item cue goto INTEGER - go to the cue index denoted by INTEGER
+=item cue goto INTEGER [TIMESTAMP] - go to the cue index denoted by INTEGER
0 is first track as returned by "cue".
Negative values of INTEGER allows selecting track relative to the last
track (-1 is the last track, -2 is the penultimate, and so on).
+The optional TIMESTAMP allows starting the index track at a given
+point, negative values allow going to a set point before the given
+index. In other words: "cue goto 1 -5" seeks to the last five seconds
+of the first track while "cue goto 1 5" seeks to the fifth second of
+the second track
+
+=item cue seek TIMESTAMP - seek within the current cue index
+
+Like the normal "seek" command, but this confines the seeking
+within the currently playing index. As with "seek",
+"+" and "-" prefixes allow seeking relative to the currently
+playing position
+
+Using a "=-" prefix allows seeking to the previous track within
+the CUE sheet, relative to the currently playing track.
=item current - output information about the current track/command in YAML
diff --git a/lib/dtas/player/client_handler.rb b/lib/dtas/player/client_handler.rb
index 8a15974..838abf7 100644
--- a/lib/dtas/player/client_handler.rb
+++ b/lib/dtas/player/client_handler.rb
@@ -186,6 +186,21 @@ def bytes_decoded(src = @current)
bytes = bytes < 0 ? 0 : bytes # maybe negative in case of sink errors
end
+ def __goto_offset_samples(offset)
+ if offset.sub!(/\A\+/, '')
+ __offset_to_samples(offset)
+ elsif offset.sub!(/\A-/, '')
+ __offset_to_samples(offset) * -1
+ else # ignore leading '=' for sox compat with 2nd "trim" arg
+ __offset_to_samples(offset)
+ end
+ end
+
+ def __offset_to_samples(offset)
+ offset.sub!(/s\z/, '') and return offset.to_i
+ @current.format.hhmmss_to_samples(offset)
+ end
+
# returns seek offset as an Integer in sample count
def __seek_offset_adj(dir, offset)
if offset.sub!(/s\z/, '')
@@ -377,7 +392,7 @@ def seek_internal(cur, offset)
end
def dpc_seek(io, msg)
- offset = msg[0]
+ offset = msg[0] or return io.emit('ERR usage: seek OFFSET')
if @current
if @current.respond_to?(:infile)
begin
@@ -730,6 +745,7 @@ def _dpc_tl_swap(io, msg)
end
def __bp_prev_next(io, msg, cur, bp)
+ # msg = [ (prev|next) [, (track|pregap|subindex|<digit>|any) ]
case type = msg[1]
when nil, "track"
bp.keep_if(&:track?)
@@ -772,6 +788,47 @@ def __bp_prev_next(io, msg, cur, bp)
io.emit("OK")
end
+ def __bp_seek(io, msg, cur, bp)
+ offset = msg[1] or return io.emit('ERR usage: cue seek OFFSET')
+
+ # relative + offset work just like normal, non-CUE "seek"
+ offset =~ /\A[\+-]/ and return dpc_seek(io, [ offset ])
+
+ # "=-" is special, it means go before the current index start:
+ dir = offset.sub!(/\A=-/, '') ? -1 : 1
+
+ begin
+ offset = __offset_to_samples(offset)
+ rescue ArgumentError
+ return io.emit('ERR bad time format')
+ end
+
+ ds = __current_decoded_samples
+ fmt = cur.format
+ prev = 0
+ bp.each do |ci|
+ ci_offset = ci.offset_samples(fmt)
+ break if ci_offset >= ds
+ prev = ci_offset
+ end
+ offset = offset * dir + prev
+ seek_internal(cur, "#{offset < 0 ? 0 : offset}s")
+ io.emit('OK')
+ end
+
+ def __bp_goto(io, msg, cur, bp)
+ index = msg[1] or return io.emit('NOINDEX')
+ ci = bp[index.to_i] or return io.emit('BADINDEX')
+ if offset = msg[2]
+ fmt = cur.format
+ offset = "#{ci.offset_samples(fmt) + __goto_offset_samples(offset)}s"
+ else
+ offset = ci.offset
+ end
+ seek_internal(cur, offset)
+ io.emit('OK')
+ end
+
def dpc_cue(io, msg)
cur = @current
if cur.respond_to?(:cuebreakpoints)
@@ -782,11 +839,8 @@ def dpc_cue(io, msg)
io.emit(tmp.to_yaml)
when "next", "prev"
return __bp_prev_next(io, msg, cur, bp)
- when "goto"
- index = msg[1] or return io.emit("NOINDEX")
- ci = bp[index.to_i] or return io.emit("BADINDEX")
- seek_internal(cur, ci.offset)
- return io.emit("OK")
+ when 'seek' then return __bp_seek(io, msg, cur, bp)
+ when 'goto' then return __bp_goto(io, msg, cur, bp)
end
else
io.emit("NOCUE")
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-04-24 2:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-11 2:27 [RFC] player: "cue prev" reliably hits previous cue breakpoint Eric Wong
2016-04-24 2:45 ` [PATCH] player: extra "cue" seeking functionality Eric Wong
Code repositories for project(s) associated with this public inbox
http://80x24.org/dtas.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).