|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:52
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 21:12:57 2012 +0200
Engine work for duet: now different tracks are analyzed.
Contains some FIXMEs though.
---
game/engine.hh | 26 +++++++++++++++++---------
game/screen_sing.cc | 14 +++++++++-----
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/game/engine.hh b/game/engine.hh
index 7fed62d..7ebeeb6 100644
--- a/game/engine.hh
+++ b/game/engine.hh
@@ -12,13 +12,13 @@
/// performous engine
class Engine {
Audio& m_audio;
- VocalTrack& m_vocal;
size_t m_time;
volatile bool m_quit;
Database& m_database;
boost::scoped_ptr<boost::thread> m_thread;
public:
+ typedef std::vector<VocalTrack*> VocalTrackPtrs;
/// timestepping constant
static const double TIMESTEP;
/** Construct a new Engine with the players that go with it.
@@ -28,17 +28,24 @@ class Engine {
* @param anEnd Analyzers to use (ending iterator)
* @param vocal Song to play
**/
- template <typename FwdIt> Engine(Audio& audio, VocalTrack& vocal, FwdIt anBegin, FwdIt anEnd, Database& database):
- m_audio(audio), m_vocal(vocal), m_time(), m_quit(), m_database(database)
+ template <typename FwdIt> Engine(Audio& audio, VocalTrackPtrs vocals, FwdIt anBegin, FwdIt anEnd, Database& database):
+ m_audio(audio), m_time(), m_quit(), m_database(database)
{
- // clear old player information
+ if (vocals.empty())
+ throw std::runtime_error("Engine needs at least one vocal track");
+ // Remove unsensibly long tracks
+ for (VocalTrackPtrs::iterator it = vocals.begin(); it != vocals.end(); )
+ if (!(*it) || (*it)->endTime > 10000.0) it = vocals.erase(it);
+ else ++it;
+ // Clear old player information
m_database.cur.clear();
m_database.scores.clear();
- // Only add players if the vocal track has sensible length (not NaN or extremely long)
- if (vocal.endTime < 10000.0) {
+ size_t i = 0;
+ while (anBegin != anEnd && !vocals.empty()) {
// Calculate the space required for pitch frames
- size_t frames = vocal.endTime / Engine::TIMESTEP;
- while (anBegin != anEnd) m_database.cur.push_back(Player(vocal, *anBegin++, frames));
+ size_t frames = vocals[i]->endTime / Engine::TIMESTEP;
+ m_database.cur.push_back(Player(*vocals[i], *anBegin++, frames));
+ i = (i+1) % vocals.size();
}
m_thread.reset(new boost::thread(boost::ref(*this)));
}
@@ -53,7 +60,8 @@ class Engine {
double timeLeft = m_time * TIMESTEP - t;
if (timeLeft != timeLeft || timeLeft > 1.0) timeLeft = 1.0; // FIXME: Workaround for NaN values and other weirdness (should fix the weirdness instead)
if (timeLeft > 0.0) { boost::thread::sleep(now() + std::min(TIMESTEP, timeLeft)); continue; }
- for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
+ // FIXME: Implement
+ //for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::update, _1));
++m_time;
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 31ab59c..eeb8240 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -56,12 +56,15 @@ void ScreenSing::enter() {
boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
reloadGL();
// Add a singer layout
+ Engine::VocalTrackPtrs selectedTracks;
+ selectedTracks.push_back(&m_song->getVocalTrack(m_selectedTrack));
m_layout_singer.clear();
- m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(m_selectedTrack), m_database, theme));
+ m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
// Find out if we have multiple vocal tracks and create layouts for them, up to a total of 2
std::vector<std::string> tracks = m_song->getVocalTrackNames();
for (size_t i = 1; i < std::min((int)tracks.size(), 2); ++i) {
- m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(tracks[i]), m_database, theme));
+ selectedTracks.push_back(&m_song->getVocalTrack(tracks[i]));
+ m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
}
// Load instrument and dance tracks
sm->loading(_("Loading instruments..."), 0.8);
@@ -100,12 +103,13 @@ void ScreenSing::enter() {
opts.push_back(*it);
}
m_vocalTrackOpts = ConfigItem(opts); // Create a ConfigItem from the option list
- if (opts.size() > 1) { // Vocal track changer only if there is options
+ // FIXME: Add a duet option without breaking track selector
+ /*if (opts.size() > 1) { // Vocal track changer only if there is options
m_vocalTrackOpts.select(cur); // Set the selection to current track
m_menu.add(MenuOption("", _("Change vocal track\n(restart required)"), &m_vocalTrackOpts));
m_selectedTrackLocalized = _(m_selectedTrack.c_str());
m_menu.back().setDynamicName(m_selectedTrackLocalized); // Set the title to be dynamic
- }
+ }*/
}
m_menu.add(MenuOption(_("Quit"), _("Exit to song browser"), "Songs"));
m_menu.close();
@@ -113,7 +117,7 @@ void ScreenSing::enter() {
double setup_delay = (m_instruments.empty() && m_dancers.empty() ? -1.0 : -5.0);
sm->loading(_("Finalizing..."), 0.95);
m_audio.playMusic(m_song->music, false, 0.0, setup_delay);
- m_engine.reset(new Engine(m_audio, m_song->getVocalTrack(m_selectedTrack), analyzers.begin(), analyzers.end(), m_database));
+ m_engine.reset(new Engine(m_audio, selectedTracks, analyzers.begin(), analyzers.end(), m_database));
// Notify about broken tracks
if (m_song->b0rkedTracks) ScreenManager::getSingletonPtr()->dialog(_("Song contains broken tracks!"));
sm->showLogo(false);
|