2011-09-28 21:44:07 +02:00
|
|
|
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice appear in all copies.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
//
|
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
#include <libaegisub/signal.h>
|
|
|
|
|
|
|
|
#include "ass_dialogue.h"
|
|
|
|
#include "ass_file.h"
|
|
|
|
#include "ass_karaoke.h"
|
2012-02-02 00:59:12 +01:00
|
|
|
#include "audio_controller.h"
|
2014-05-23 00:40:16 +02:00
|
|
|
#include "audio_marker.h"
|
|
|
|
#include "audio_rendering_style.h"
|
2011-09-28 21:44:07 +02:00
|
|
|
#include "audio_timing.h"
|
2012-12-30 00:53:56 +01:00
|
|
|
#include "compat.h"
|
2011-09-28 21:44:07 +02:00
|
|
|
#include "include/aegisub/context.h"
|
2013-01-07 02:50:09 +01:00
|
|
|
#include "options.h"
|
2011-10-19 06:19:01 +02:00
|
|
|
#include "pen.h"
|
2014-03-25 01:15:14 +01:00
|
|
|
#include "selection_controller.h"
|
2011-09-28 21:44:07 +02:00
|
|
|
#include "utils.h"
|
|
|
|
|
2014-04-23 22:53:24 +02:00
|
|
|
#include <libaegisub/make_unique.h>
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-12-01 03:47:24 +01:00
|
|
|
#include <boost/range/algorithm/copy.hpp>
|
2012-12-01 00:07:35 +01:00
|
|
|
#include <boost/range/adaptor/filtered.hpp>
|
|
|
|
#include <boost/range/adaptor/sliced.hpp>
|
2014-05-23 00:40:16 +02:00
|
|
|
#include <wx/intl.h>
|
2012-12-01 00:07:35 +01:00
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
/// @class KaraokeMarker
|
|
|
|
/// @brief AudioMarker implementation for AudioTimingControllerKaraoke
|
2014-03-13 02:39:07 +01:00
|
|
|
class KaraokeMarker final : public AudioMarker {
|
2012-02-02 00:58:58 +01:00
|
|
|
int position;
|
2014-05-12 18:30:14 +02:00
|
|
|
Pen *pen = nullptr;
|
|
|
|
FeetStyle style = Feet_None;
|
2011-09-28 21:44:07 +02:00
|
|
|
public:
|
|
|
|
|
2013-11-21 18:13:36 +01:00
|
|
|
int GetPosition() const override { return position; }
|
|
|
|
wxPen GetStyle() const override { return *pen; }
|
|
|
|
FeetStyle GetFeet() const override { return style; }
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
void Move(int new_pos) { position = new_pos; }
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2014-05-22 01:23:28 +02:00
|
|
|
KaraokeMarker(int position) : position(position) { }
|
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
KaraokeMarker(int position, Pen *pen, FeetStyle style)
|
2011-09-28 21:44:07 +02:00
|
|
|
: position(position)
|
|
|
|
, pen(pen)
|
|
|
|
, style(style)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
operator int() const { return position; }
|
2011-09-28 21:44:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/// @class AudioTimingControllerKaraoke
|
|
|
|
/// @brief Karaoke timing mode for timing subtitles
|
|
|
|
///
|
|
|
|
/// Displays the active line with draggable markers between each pair of
|
|
|
|
/// adjacent syllables, along with the text of each syllable.
|
|
|
|
///
|
|
|
|
/// This does not support \kt, as it inherently requires that the end time of
|
|
|
|
/// one syllable be the same as the start time of the next one.
|
2014-03-13 02:39:07 +01:00
|
|
|
class AudioTimingControllerKaraoke final : public AudioTimingController {
|
2014-05-22 01:23:28 +02:00
|
|
|
std::vector<agi::signal::Connection> connections;
|
2011-09-28 21:44:07 +02:00
|
|
|
agi::signal::Connection& file_changed_slot;
|
|
|
|
|
|
|
|
agi::Context *c; ///< Project context
|
|
|
|
AssDialogue *active_line; ///< Currently active line
|
|
|
|
AssKaraoke *kara; ///< Parsed karaoke model provided by karaoke controller
|
|
|
|
|
2013-12-12 01:29:48 +01:00
|
|
|
size_t cur_syl = 0; ///< Index of currently selected syllable in the line
|
2011-09-28 21:44:07 +02:00
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
/// Index of marker serving as tap marker
|
|
|
|
/// For AudioControllerTimingKaraoke:
|
|
|
|
/// - 0 is start marker
|
|
|
|
/// - 1 to markers.size() is a regular syllable marker
|
|
|
|
/// - markers.size() + 1 is end marker
|
|
|
|
size_t tap_marker_idx = 0;
|
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
/// Pen used for the mid-syllable markers
|
2014-05-12 18:30:14 +02:00
|
|
|
Pen separator_pen{"Colour/Audio Display/Syllable Boundaries", "Audio/Line Boundaries Thickness", wxPENSTYLE_DOT};
|
2011-09-28 21:44:07 +02:00
|
|
|
/// Pen used for the start-of-line marker
|
2014-05-12 18:30:14 +02:00
|
|
|
Pen start_pen{"Colour/Audio Display/Line boundary Start", "Audio/Line Boundaries Thickness"};
|
2011-09-28 21:44:07 +02:00
|
|
|
/// Pen used for the end-of-line marker
|
2014-05-12 18:30:14 +02:00
|
|
|
Pen end_pen{"Colour/Audio Display/Line boundary End", "Audio/Line Boundaries Thickness"};
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
/// Immobile marker for the beginning of the line
|
|
|
|
KaraokeMarker start_marker;
|
|
|
|
/// Immobile marker for the end of the line
|
|
|
|
KaraokeMarker end_marker;
|
|
|
|
/// Mobile markers between each pair of syllables
|
|
|
|
std::vector<KaraokeMarker> markers;
|
|
|
|
|
2011-11-16 20:56:00 +01:00
|
|
|
/// Marker provider for video keyframes
|
|
|
|
AudioMarkerProviderKeyframes keyframes_provider;
|
|
|
|
|
2012-02-02 00:59:12 +01:00
|
|
|
/// Marker provider for video playback position
|
|
|
|
VideoPositionMarkerProvider video_position_provider;
|
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
/// Labels containing the stripped text of each syllable
|
|
|
|
std::vector<AudioLabel> labels;
|
|
|
|
|
2014-05-12 18:30:14 +02:00
|
|
|
/// Should changes be automatically commited?
|
|
|
|
bool auto_commit = OPT_GET("Audio/Auto/Commit")->GetBool();
|
2013-12-12 01:29:48 +01:00
|
|
|
int commit_id = -1; ///< Last commit id used for an autocommit
|
2012-11-03 23:40:54 +01:00
|
|
|
bool pending_changes; ///< Are there any pending changes to be committed?
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
void DoCommit();
|
2012-02-22 23:00:54 +01:00
|
|
|
void ApplyLead(bool announce_primary);
|
2012-07-14 15:35:15 +02:00
|
|
|
int MoveMarker(KaraokeMarker *marker, int new_position);
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
void MoveStartMarker(int new_position);
|
|
|
|
void MoveEndMarker(int new_position);
|
|
|
|
void CompressMarkers(size_t from, size_t to, int new_position);
|
|
|
|
void AnnounceChanges(bool announce_primary);
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
// AudioTimingController implementation
|
2013-11-21 18:13:36 +01:00
|
|
|
void GetMarkers(const TimeRange &range, AudioMarkerVector &out_markers) const override;
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
int GetTapMarkerPosition() const override;
|
|
|
|
size_t GetTapMarkerIndex() const override;
|
2013-11-21 18:13:36 +01:00
|
|
|
wxString GetWarningMessage() const override { return ""; }
|
|
|
|
TimeRange GetIdealVisibleTimeRange() const override;
|
|
|
|
void GetRenderingStyles(AudioRenderingStyleRanges &ranges) const override;
|
|
|
|
TimeRange GetPrimaryPlaybackRange() const override;
|
|
|
|
TimeRange GetActiveLineRange() const override;
|
|
|
|
void GetLabels(const TimeRange &range, std::vector<AudioLabel> &out_labels) const override;
|
|
|
|
void Next(NextMode mode) override;
|
|
|
|
void Prev() override;
|
|
|
|
void Commit() override;
|
|
|
|
void Revert() override;
|
|
|
|
void AddLeadIn() override;
|
|
|
|
void AddLeadOut() override;
|
|
|
|
void ModifyLength(int delta, bool shift_following) override;
|
|
|
|
void ModifyStart(int delta) override;
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
void MoveTapMarker(int ms) override;
|
|
|
|
bool NextTapMarker() override;
|
2014-05-14 15:40:01 +02:00
|
|
|
bool IsNearbyMarker(int ms, int sensitivity, bool) const override;
|
2014-05-12 21:07:46 +02:00
|
|
|
std::vector<AudioMarker*> OnLeftClick(int ms, bool, bool, int sensitivity, int) override;
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
std::vector<AudioMarker*> OnRightClick(int ms, bool ctrl_down, int, int) override;
|
2013-11-21 18:13:36 +01:00
|
|
|
void OnMarkerDrag(std::vector<AudioMarker*> const& marker, int new_position, int) override;
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
AudioTimingControllerKaraoke(agi::Context *c, AssKaraoke *kara, agi::signal::Connection& file_changed);
|
|
|
|
};
|
|
|
|
|
2014-04-23 01:21:53 +02:00
|
|
|
std::unique_ptr<AudioTimingController> CreateKaraokeTimingController(agi::Context *c, AssKaraoke *kara, agi::signal::Connection& file_changed)
|
2011-09-28 21:44:07 +02:00
|
|
|
{
|
2014-04-23 22:53:24 +02:00
|
|
|
return agi::make_unique<AudioTimingControllerKaraoke>(c, kara, file_changed);
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AudioTimingControllerKaraoke::AudioTimingControllerKaraoke(agi::Context *c, AssKaraoke *kara, agi::signal::Connection& file_changed)
|
|
|
|
: file_changed_slot(file_changed)
|
|
|
|
, c(c)
|
|
|
|
, active_line(c->selectionController->GetActiveLine())
|
|
|
|
, kara(kara)
|
2012-02-02 00:58:58 +01:00
|
|
|
, start_marker(active_line->Start, &start_pen, AudioMarker::Feet_Right)
|
|
|
|
, end_marker(active_line->End, &end_pen, AudioMarker::Feet_Left)
|
2011-11-16 20:56:09 +01:00
|
|
|
, keyframes_provider(c, "Audio/Display/Draw/Keyframes in Karaoke Mode")
|
2012-02-02 00:59:12 +01:00
|
|
|
, video_position_provider(c)
|
2011-09-28 21:44:07 +02:00
|
|
|
{
|
2014-05-22 01:23:28 +02:00
|
|
|
connections.push_back(kara->AddSyllablesChangedListener(&AudioTimingControllerKaraoke::Revert, this));
|
|
|
|
connections.push_back(OPT_SUB("Audio/Auto/Commit", [=](agi::OptionValue const& opt) { auto_commit = opt.GetBool(); }));
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2014-04-24 00:48:39 +02:00
|
|
|
keyframes_provider.AddMarkerMovedListener([=]{ AnnounceMarkerMoved(); });
|
|
|
|
video_position_provider.AddMarkerMovedListener([=]{ AnnounceMarkerMoved(); });
|
2011-11-16 20:56:00 +01:00
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
Revert();
|
|
|
|
}
|
|
|
|
|
2012-04-27 21:07:07 +02:00
|
|
|
void AudioTimingControllerKaraoke::Next(NextMode mode) {
|
|
|
|
// Don't create new lines since it's almost never useful to k-time a line
|
|
|
|
// before dialogue timing it
|
|
|
|
if (mode != TIMING_UNIT)
|
|
|
|
cur_syl = markers.size();
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
++cur_syl;
|
|
|
|
if (cur_syl > markers.size()) {
|
|
|
|
--cur_syl;
|
|
|
|
c->selectionController->NextLine();
|
|
|
|
}
|
2011-11-18 23:58:22 +01:00
|
|
|
else {
|
2011-09-28 21:44:07 +02:00
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
|
|
|
}
|
2012-01-22 18:15:25 +01:00
|
|
|
|
|
|
|
c->audioController->PlayPrimaryRange();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::Prev() {
|
|
|
|
if (cur_syl == 0) {
|
|
|
|
AssDialogue *old_line = active_line;
|
|
|
|
c->selectionController->PrevLine();
|
|
|
|
if (old_line != active_line) {
|
|
|
|
cur_syl = markers.size();
|
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
--cur_syl;
|
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
2012-01-22 18:15:25 +01:00
|
|
|
|
|
|
|
c->audioController->PlayPrimaryRange();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
2011-11-18 23:56:45 +01:00
|
|
|
void AudioTimingControllerKaraoke::GetRenderingStyles(AudioRenderingStyleRanges &ranges) const
|
|
|
|
{
|
2012-02-02 00:58:58 +01:00
|
|
|
TimeRange sr = GetPrimaryPlaybackRange();
|
2012-02-17 01:14:45 +01:00
|
|
|
ranges.AddRange(sr.begin(), sr.end(), AudioStyle_Primary);
|
2012-03-12 01:07:22 +01:00
|
|
|
ranges.AddRange(start_marker, end_marker, AudioStyle_Selected);
|
2011-11-18 23:56:45 +01:00
|
|
|
}
|
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
TimeRange AudioTimingControllerKaraoke::GetPrimaryPlaybackRange() const {
|
|
|
|
return TimeRange(
|
2011-09-28 21:44:07 +02:00
|
|
|
cur_syl > 0 ? markers[cur_syl - 1] : start_marker,
|
|
|
|
cur_syl < markers.size() ? markers[cur_syl] : end_marker);
|
|
|
|
}
|
|
|
|
|
2012-10-05 01:15:45 +02:00
|
|
|
TimeRange AudioTimingControllerKaraoke::GetActiveLineRange() const {
|
2012-02-02 00:58:58 +01:00
|
|
|
return TimeRange(start_marker, end_marker);
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
2012-10-05 01:15:45 +02:00
|
|
|
TimeRange AudioTimingControllerKaraoke::GetIdealVisibleTimeRange() const {
|
|
|
|
return GetActiveLineRange();
|
|
|
|
}
|
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
void AudioTimingControllerKaraoke::GetMarkers(TimeRange const& range, AudioMarkerVector &out) const {
|
2011-09-28 21:44:07 +02:00
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < markers.size() && markers[i] < range.begin(); ++i) ;
|
|
|
|
for (; i < markers.size() && markers[i] < range.end(); ++i)
|
|
|
|
out.push_back(&markers[i]);
|
|
|
|
|
|
|
|
if (range.contains(start_marker)) out.push_back(&start_marker);
|
|
|
|
if (range.contains(end_marker)) out.push_back(&end_marker);
|
2011-11-16 20:56:00 +01:00
|
|
|
|
|
|
|
keyframes_provider.GetMarkers(range, out);
|
2012-02-02 00:59:12 +01:00
|
|
|
video_position_provider.GetMarkers(range, out);
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
int AudioTimingControllerKaraoke::GetTapMarkerPosition() const {
|
|
|
|
assert(tap_marker_idx <= markers.size() + 1);
|
|
|
|
|
|
|
|
if (tap_marker_idx == 0) {
|
|
|
|
return start_marker;
|
|
|
|
}
|
|
|
|
else if (tap_marker_idx < markers.size() + 1) {
|
|
|
|
return markers[tap_marker_idx-1];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return end_marker;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t AudioTimingControllerKaraoke::GetTapMarkerIndex() const {
|
|
|
|
assert(tap_marker_idx <= markers.size() + 1);
|
|
|
|
return tap_marker_idx;
|
|
|
|
}
|
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
void AudioTimingControllerKaraoke::DoCommit() {
|
|
|
|
active_line->Text = kara->GetText();
|
|
|
|
file_changed_slot.Block();
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
commit_id = c->ass->Commit(_("karaoke timing"), AssFile::COMMIT_DIAG_TEXT | AssFile::COMMIT_DIAG_TIME, commit_id, active_line);
|
2011-09-28 21:44:07 +02:00
|
|
|
file_changed_slot.Unblock();
|
2012-11-03 23:40:54 +01:00
|
|
|
pending_changes = false;
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::Commit() {
|
2012-11-03 23:40:54 +01:00
|
|
|
if (!auto_commit && pending_changes)
|
2011-09-30 22:42:28 +02:00
|
|
|
DoCommit();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::Revert() {
|
|
|
|
active_line = c->selectionController->GetActiveLine();
|
|
|
|
|
|
|
|
cur_syl = 0;
|
|
|
|
commit_id = -1;
|
2012-11-03 23:40:54 +01:00
|
|
|
pending_changes = false;
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
tap_marker_idx = 0;
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
start_marker.Move(active_line->Start);
|
|
|
|
end_marker.Move(active_line->End);
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
markers.clear();
|
|
|
|
labels.clear();
|
|
|
|
|
|
|
|
markers.reserve(kara->size());
|
|
|
|
labels.reserve(kara->size());
|
|
|
|
|
2012-12-23 00:35:13 +01:00
|
|
|
for (auto it = kara->begin(); it != kara->end(); ++it) {
|
2011-09-28 21:44:07 +02:00
|
|
|
if (it != kara->begin())
|
2012-11-28 16:35:26 +01:00
|
|
|
markers.emplace_back(it->start_time, &separator_pen, AudioMarker::Feet_None);
|
2014-04-25 19:01:07 +02:00
|
|
|
labels.push_back(AudioLabel{to_wx(it->text), TimeRange(it->start_time, it->start_time + it->duration)});
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
2011-11-16 20:56:00 +01:00
|
|
|
AnnounceMarkerMoved();
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceUpdatedTapMarker();
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
2012-02-22 23:00:54 +01:00
|
|
|
void AudioTimingControllerKaraoke::AddLeadIn() {
|
|
|
|
start_marker.Move(start_marker - OPT_GET("Audio/Lead/IN")->GetInt());
|
|
|
|
labels.front().range = TimeRange(start_marker, labels.front().range.end());
|
|
|
|
ApplyLead(cur_syl == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::AddLeadOut() {
|
|
|
|
end_marker.Move(end_marker + OPT_GET("Audio/Lead/OUT")->GetInt());
|
|
|
|
labels.back().range = TimeRange(labels.back().range.begin(), end_marker);
|
|
|
|
ApplyLead(cur_syl == markers.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::ApplyLead(bool announce_primary) {
|
2012-09-25 03:56:49 +02:00
|
|
|
active_line->Start = (int)start_marker;
|
|
|
|
active_line->End = (int)end_marker;
|
2012-02-22 23:00:54 +01:00
|
|
|
kara->SetLineTimes(start_marker, end_marker);
|
2012-07-14 15:35:15 +02:00
|
|
|
if (!announce_primary)
|
|
|
|
AnnounceUpdatedStyleRanges();
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceChanges(announce_primary);
|
2012-07-14 15:35:15 +02:00
|
|
|
}
|
2012-02-22 23:00:54 +01:00
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
void AudioTimingControllerKaraoke::ModifyLength(int delta, bool shift_following) {
|
|
|
|
if (cur_syl == markers.size()) return;
|
2012-02-22 23:00:54 +01:00
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
int cur, end, step;
|
|
|
|
if (delta < 0) {
|
|
|
|
cur = cur_syl;
|
|
|
|
end = shift_following ? markers.size() : cur_syl + 1;
|
|
|
|
step = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cur = shift_following ? markers.size() - 1 : cur_syl;
|
|
|
|
end = cur_syl - 1;
|
|
|
|
step = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; cur != end; cur += step) {
|
|
|
|
MoveMarker(&markers[cur], markers[cur] + delta * 10);
|
|
|
|
}
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceChanges(true);
|
2012-07-14 15:35:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::ModifyStart(int delta) {
|
|
|
|
if (cur_syl == 0) return;
|
|
|
|
MoveMarker(&markers[cur_syl - 1], markers[cur_syl - 1] + delta * 10);
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceChanges(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::MoveTapMarker(int ms) {
|
|
|
|
// Fix rounding error
|
|
|
|
ms = (ms + 5) / 10 * 10;
|
|
|
|
|
|
|
|
// Get syllable this time falls within
|
|
|
|
const size_t syl = distance(markers.begin(), lower_bound(markers.begin(), markers.end(), ms));
|
|
|
|
|
2018-10-28 20:01:13 +01:00
|
|
|
// Tapping automatically moves all of the necessary markers for the tap
|
|
|
|
// marker to land at the current audio position. Intuitively, it "pushes" or
|
|
|
|
// "compresses" the markers blocking the tap marker's way so they all end up
|
|
|
|
// in the same position. The expectation is that the markers will reach their
|
|
|
|
// proper position once the user finishes tapping to the line
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
if (tap_marker_idx == 0) {
|
|
|
|
// Moving the start time of first syllable (i.e. start time of the line)
|
|
|
|
if (ms > end_marker) MoveEndMarker(ms);
|
|
|
|
if (syl > 0) CompressMarkers(syl-1, 0, ms);
|
|
|
|
MoveStartMarker(ms);
|
|
|
|
}
|
|
|
|
else if (tap_marker_idx < markers.size() + 1) {
|
|
|
|
// Moving the end time of a non-end syllable
|
|
|
|
if (ms < start_marker) MoveStartMarker(ms);
|
|
|
|
else if (ms > end_marker) MoveEndMarker(ms);
|
|
|
|
if (syl < tap_marker_idx) {
|
2018-10-28 20:01:13 +01:00
|
|
|
// Moving markers left
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
CompressMarkers(syl, tap_marker_idx-1, ms);
|
|
|
|
}
|
|
|
|
else {
|
2018-10-28 20:01:13 +01:00
|
|
|
// Moving markers right
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
CompressMarkers(syl-1, tap_marker_idx-1, ms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Moving the end time of last syllable (i.e. end time of the line)
|
|
|
|
if (ms < start_marker) MoveStartMarker(ms);
|
|
|
|
if (syl < markers.size()) CompressMarkers(0, markers.size()-1, ms);
|
|
|
|
MoveEndMarker(ms);
|
|
|
|
}
|
|
|
|
|
|
|
|
AnnounceChanges(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AudioTimingControllerKaraoke::NextTapMarker() {
|
|
|
|
if (tap_marker_idx < markers.size() + 1) {
|
|
|
|
++tap_marker_idx;
|
|
|
|
AnnounceUpdatedTapMarker();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2012-02-22 23:00:54 +01:00
|
|
|
}
|
|
|
|
|
2014-05-14 15:40:01 +02:00
|
|
|
bool AudioTimingControllerKaraoke::IsNearbyMarker(int ms, int sensitivity, bool) const {
|
2012-02-02 00:58:58 +01:00
|
|
|
TimeRange range(ms - sensitivity, ms + sensitivity);
|
2012-12-01 00:07:35 +01:00
|
|
|
return any_of(markers.begin(), markers.end(), [&](KaraokeMarker const& km) {
|
|
|
|
return range.contains(km);
|
|
|
|
});
|
|
|
|
}
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-12-01 00:07:35 +01:00
|
|
|
template<typename Out, typename In>
|
|
|
|
static std::vector<Out *> copy_ptrs(In &vec, size_t start, size_t end) {
|
|
|
|
std::vector<Out *> ret;
|
|
|
|
ret.reserve(end - start);
|
|
|
|
for (; start < end; ++start)
|
|
|
|
ret.push_back(&vec[start]);
|
|
|
|
return ret;
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
2014-05-12 21:07:46 +02:00
|
|
|
std::vector<AudioMarker*> AudioTimingControllerKaraoke::OnLeftClick(int ms, bool ctrl_down, bool, int sensitivity, int) {
|
2012-02-02 00:58:58 +01:00
|
|
|
TimeRange range(ms - sensitivity, ms + sensitivity);
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
size_t syl = distance(markers.begin(), lower_bound(markers.begin(), markers.end(), ms));
|
2011-09-28 21:44:07 +02:00
|
|
|
if (syl < markers.size() && range.contains(markers[syl]))
|
2012-12-01 00:07:35 +01:00
|
|
|
return copy_ptrs<AudioMarker>(markers, syl, ctrl_down ? markers.size() : syl + 1);
|
2011-09-28 21:44:07 +02:00
|
|
|
if (syl > 0 && range.contains(markers[syl - 1]))
|
2012-12-01 00:07:35 +01:00
|
|
|
return copy_ptrs<AudioMarker>(markers, syl - 1, ctrl_down ? markers.size() : syl);
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
cur_syl = syl;
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
// Change tap marker
|
|
|
|
// Selecting a syllable moves the marker to the _end_ of that syllable, such
|
|
|
|
// that the next tap determines when that syllable ends. This behavior is
|
|
|
|
// more intuitive when coupled with AudioKaraoke's tap syllable highlight.
|
|
|
|
if (ms < start_marker.GetPosition()) {
|
|
|
|
tap_marker_idx = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tap_marker_idx = cur_syl + 1;
|
|
|
|
}
|
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceUpdatedTapMarker();
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2013-12-12 00:11:06 +01:00
|
|
|
return {};
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
std::vector<AudioMarker*> AudioTimingControllerKaraoke::OnRightClick(int ms, bool ctrl_down, int, int) {
|
|
|
|
if (ctrl_down) {
|
2018-10-28 20:01:13 +01:00
|
|
|
// Ctrl-right-click: play audio
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
c->audioController->PlayToEnd(ms);
|
2018-10-28 20:01:13 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Normal right-click: select new syllable and play range
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
cur_syl = distance(markers.begin(), lower_bound(markers.begin(), markers.end(), ms));
|
|
|
|
AnnounceUpdatedPrimaryRange();
|
|
|
|
AnnounceUpdatedStyleRanges();
|
|
|
|
c->audioController->PlayPrimaryRange();
|
|
|
|
}
|
2012-10-16 23:08:20 +02:00
|
|
|
|
2013-12-12 00:11:06 +01:00
|
|
|
return {};
|
2012-10-16 23:08:20 +02:00
|
|
|
}
|
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
int AudioTimingControllerKaraoke::MoveMarker(KaraokeMarker *marker, int new_position) {
|
2011-09-28 21:44:07 +02:00
|
|
|
// No rearranging of syllables allowed
|
|
|
|
new_position = mid(
|
|
|
|
marker == &markers.front() ? start_marker.GetPosition() : (marker - 1)->GetPosition(),
|
|
|
|
new_position,
|
|
|
|
marker == &markers.back() ? end_marker.GetPosition() : (marker + 1)->GetPosition());
|
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
if (new_position == marker->GetPosition())
|
|
|
|
return -1;
|
|
|
|
|
2011-09-28 21:44:07 +02:00
|
|
|
marker->Move(new_position);
|
|
|
|
|
|
|
|
size_t syl = marker - &markers.front() + 1;
|
2018-10-21 09:33:29 +02:00
|
|
|
kara->SetStartTime(syl, new_position);
|
2011-09-28 21:44:07 +02:00
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
labels[syl - 1].range = TimeRange(labels[syl - 1].range.begin(), new_position);
|
|
|
|
labels[syl].range = TimeRange(new_position, labels[syl].range.end());
|
|
|
|
|
|
|
|
return syl;
|
|
|
|
}
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
void AudioTimingControllerKaraoke::MoveStartMarker(int new_position) {
|
|
|
|
// No rearranging of syllables allowed
|
|
|
|
new_position = mid(
|
|
|
|
0,
|
|
|
|
new_position,
|
|
|
|
markers[0].GetPosition());
|
|
|
|
|
|
|
|
if (new_position == start_marker.GetPosition())
|
|
|
|
return;
|
|
|
|
|
|
|
|
start_marker.Move(new_position);
|
|
|
|
|
|
|
|
active_line->Start = (int)start_marker;
|
|
|
|
kara->SetLineTimes(start_marker, end_marker);
|
|
|
|
|
|
|
|
labels.front().range = TimeRange(start_marker, labels.front().range.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::MoveEndMarker(int new_position) {
|
|
|
|
// No rearranging of syllables allowed
|
|
|
|
new_position = mid(
|
|
|
|
markers.back().GetPosition(),
|
|
|
|
new_position,
|
|
|
|
INT_MAX);
|
|
|
|
|
|
|
|
if (new_position == end_marker.GetPosition())
|
|
|
|
return;
|
|
|
|
|
|
|
|
end_marker.Move(new_position);
|
|
|
|
|
|
|
|
active_line->End = (int)end_marker;
|
|
|
|
kara->SetLineTimes(start_marker, end_marker);
|
|
|
|
|
|
|
|
labels.back().range = TimeRange(labels.back().range.begin(), end_marker);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AudioTimingControllerKaraoke::CompressMarkers(size_t from, size_t to, int new_position) {
|
|
|
|
int incr = (from < to ? 1 : -1);
|
|
|
|
size_t i = from;
|
|
|
|
for (;;) {
|
|
|
|
MoveMarker(&markers[i], new_position);
|
|
|
|
if (i == to) {
|
|
|
|
break;
|
2018-10-28 20:01:13 +01:00
|
|
|
}
|
|
|
|
else {
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
i += incr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-07-14 15:35:15 +02:00
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
void AudioTimingControllerKaraoke::AnnounceChanges(bool announce_primary) {
|
|
|
|
if (announce_primary) {
|
2011-09-28 21:44:07 +02:00
|
|
|
AnnounceUpdatedPrimaryRange();
|
2011-11-18 23:58:22 +01:00
|
|
|
AnnounceUpdatedStyleRanges();
|
|
|
|
}
|
2011-11-16 20:56:00 +01:00
|
|
|
AnnounceMarkerMoved();
|
|
|
|
AnnounceLabelChanged();
|
2011-09-28 21:44:07 +02:00
|
|
|
|
|
|
|
if (auto_commit)
|
|
|
|
DoCommit();
|
2012-11-03 23:40:54 +01:00
|
|
|
else {
|
|
|
|
pending_changes = true;
|
2011-09-28 21:44:07 +02:00
|
|
|
commit_id = -1;
|
2012-11-03 23:40:54 +01:00
|
|
|
}
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|
|
|
|
|
2012-07-14 15:35:15 +02:00
|
|
|
void AudioTimingControllerKaraoke::OnMarkerDrag(std::vector<AudioMarker*> const& m, int new_position, int) {
|
2018-10-21 09:33:29 +02:00
|
|
|
// Fix rounding error
|
|
|
|
new_position = (new_position + 5) / 10 * 10;
|
2012-12-01 00:07:35 +01:00
|
|
|
int old_position = m[0]->GetPosition();
|
|
|
|
int syl = MoveMarker(static_cast<KaraokeMarker *>(m[0]), new_position);
|
|
|
|
if (syl < 0) return;
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
bool announce_primary = (syl == cur_syl || syl == cur_syl + 1);
|
2012-12-01 00:07:35 +01:00
|
|
|
if (m.size() > 1) {
|
|
|
|
int delta = m[0]->GetPosition() - old_position;
|
|
|
|
for (AudioMarker *marker : m | boost::adaptors::sliced(1, m.size()))
|
|
|
|
MoveMarker(static_cast<KaraokeMarker *>(marker), marker->GetPosition() + delta);
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
announce_primary = true;
|
2012-12-01 00:07:35 +01:00
|
|
|
}
|
|
|
|
|
Audio/Timing: implement tap-to-time
Tap-to-time provides the user the ability to tap to the lyrics/syllables
of the song in order to time lines or karaoke. It consists of these
extra UI interactions:
- **Indicator**: tap marker: a designated marker that can be moved to
the current audio position; indicated in:
- the audio display by a green arrow underneath a marker
- the karaoke display by a green-colored syllable
- **Control**: tap marker: the tap marker can be changed by selecting
syllables on audio display in karaoke mode, or clicking the markers on
audio display in dialogue mode
- **Control**: ctrl-right-click audio display: starts playing the audio
from that exact position until the end of the file
- **Option**: Timing/Tap To Time: enables the tap marker indicator and
commands
- **Button**: time_opt_tap_to_time: toggles the Timing/Tap To Time option
- **Button**: time_tap_connect (hotkey I): a command that:
- moves the tap marker's position to the current playing audio
position
- sets the next marker to be the tap marker
- if the tap marker is already the last marker AND BOTH autocommit AND
next-line-on-commit is ON, will move onto the next line
- if moved on to the next line, also sets the start marker to the current
audio position, so the two lines are connected, and moves to the
next tap marker (essentially reinvoking time_tap_connect once)
- **Button**: time_tap_no_connect (hotkey O): similar to
time_tap_connect, except it will not set the next line's start
position even if moved to the next line
Expected workflow:
1) User loads song lyrics
2) User splits each line into syllables
3) User turns on tap-to-time, autocommit, and next-line-on-commit
4) User plays audio from beginning, tapping time_tap_connect to each
syllable, occasionally tapping time_tap_no_connect when a break between
lines is desired
5) If user messes up a line, they can set the tap marker to where they
want to restart from, and ctrl-right-click to start the audio a few
seconds before it
6) Syllables can be split/merged at will, and adjustments to timing can
be done using normal karaoke timing controls
2018-10-21 09:42:33 +02:00
|
|
|
AnnounceChanges(announce_primary);
|
2012-07-14 15:35:15 +02:00
|
|
|
}
|
|
|
|
|
2012-02-02 00:58:58 +01:00
|
|
|
void AudioTimingControllerKaraoke::GetLabels(TimeRange const& range, std::vector<AudioLabel> &out) const {
|
2012-12-01 03:47:24 +01:00
|
|
|
copy(labels | boost::adaptors::filtered([&](AudioLabel const& l) {
|
2012-12-01 00:07:35 +01:00
|
|
|
return range.overlaps(l.range);
|
2012-12-01 03:47:24 +01:00
|
|
|
}), back_inserter(out));
|
2011-09-28 21:44:07 +02:00
|
|
|
}
|