You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(25) |
Jul
(288) |
Aug
(119) |
Sep
(31) |
Oct
(59) |
Nov
(458) |
Dec
(359) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(268) |
Feb
(26) |
Mar
(36) |
Apr
(48) |
May
(119) |
Jun
(37) |
Jul
(173) |
Aug
(429) |
Sep
(137) |
Oct
(156) |
Nov
(59) |
Dec
(45) |
| 2011 |
Jan
(398) |
Feb
(257) |
Mar
(49) |
Apr
(5) |
May
(34) |
Jun
(11) |
Jul
(38) |
Aug
(12) |
Sep
(1) |
Oct
(49) |
Nov
(5) |
Dec
(10) |
| 2012 |
Jan
(21) |
Feb
(32) |
Mar
(20) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(173) |
Aug
|
Sep
(25) |
Oct
(6) |
Nov
(44) |
Dec
|
|
From: Tapio V. <aa...@us...> - 2010-07-07 17:07:19
|
Module: performous Branch: joinmenu Commit: 66ed99a828793db65edcf4d13471b5378ad0170d Author: Tapio Vierros <tap...@gm...> Date: Mon Jun 21 23:06:10 2010 +0300 Remove executable bit from a few source files. --- 0 files changed, 0 insertions(+), 0 deletions(-) diff --git a/game/menu.cc b/game/menu.cc old mode 100755 new mode 100644 diff --git a/game/menu.hh b/game/menu.hh old mode 100755 new mode 100644 diff --git a/game/screen_intro.cc b/game/screen_intro.cc old mode 100755 new mode 100644 diff --git a/game/screen_intro.hh b/game/screen_intro.hh old mode 100755 new mode 100644 diff --git a/game/theme.cc b/game/theme.cc old mode 100755 new mode 100644 diff --git a/game/theme.hh b/game/theme.hh old mode 100755 new mode 100644 |
|
From: Tapio V. <aa...@us...> - 2010-07-07 15:45:07
|
Module: performous Branch: joinmenu Commit: d709b2079842e00ebd1cd513f6ef363599568125 Author: Tapio Vierros <tap...@gm...> Date: Wed Jul 7 18:43:05 2010 +0300 Add screen changer menu option type and re-implement screen_intro using it. This also allows quitting from songs. --- game/configuration.cc | 8 ++++---- game/instrumentgraph.cc | 2 +- game/menu.cc | 19 +++++++++++++++---- game/menu.hh | 26 ++++++++------------------ game/screen_intro.cc | 43 ++++++++++++++++++++----------------------- game/screen_intro.hh | 3 +-- game/theme.cc | 5 +---- game/theme.hh | 2 +- 8 files changed, 51 insertions(+), 57 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2010-07-07 15:45:06
|
Module: performous
Branch: joinmenu
Commit: 47e8b7b1325537952e7ddbd64d6708173d72c46b
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jul 7 18:02:16 2010 +0300
Implement exit from menu root, enables joining game.
---
game/dancegraph.cc | 7 ++++---
game/guitargraph.cc | 9 +++++----
game/instrumentgraph.cc | 14 ++++++++------
game/instrumentgraph.hh | 6 +++---
game/menu.cc | 10 +++++++++-
game/menu.hh | 14 ++++++++++++--
game/screen_sing.cc | 4 ++--
7 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/game/dancegraph.cc b/game/dancegraph.cc
index cbf296b..9da8c40 100644
--- a/game/dancegraph.cc
+++ b/game/dancegraph.cc
@@ -188,6 +188,7 @@ void DanceGraph::difficulty(DanceDifficulty level) {
void DanceGraph::engine() {
double time = m_audio.getPosition();
time -= config["audio/controller_delay"].f();
+ doUpdates();
for (Song::Stops::const_iterator it = m_song.stops.begin(), end = m_song.stops.end(); it != end; ++it) {
if (it->first >= time) break;
if (time < it->first + it->second) { time = it->first; break; } // Inside stop
@@ -203,8 +204,8 @@ void DanceGraph::engine() {
break;
}
// Menu keys
- if (m_menuOpen && ev.type == input::Event::PRESS) {
- if (ev.nav == input::CANCEL) toggleMenu();
+ if (menuOpen() && ev.type == input::Event::PRESS) {
+ if (ev.nav == input::CANCEL) m_menu.close();
else if (ev.nav == input::RIGHT || ev.nav == input::START) m_menu.action(1);
else if (ev.nav == input::LEFT) m_menu.action(-1);
else if (ev.nav == input::UP) m_menu.move(-1);
@@ -477,7 +478,7 @@ void DanceGraph::drawNote(DanceNote& note, double time) {
/// Draw popups and other info texts
void DanceGraph::drawInfo(double time, double offsetX, Dimensions dimensions) {
- if (m_menuOpen) {
+ if (menuOpen()) {
// Draw join menu
drawMenu(offsetX);
} else {
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 8edb882..dc38224 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -206,6 +206,7 @@ bool GuitarGraph::difficulty(Difficulty level) {
void GuitarGraph::engine() {
double time = m_audio.getPosition();
time -= config["audio/controller_delay"].f();
+ doUpdates();
// Handle key markers
if (!m_drums) {
for (int i = 0; i < m_pads; ++i) {
@@ -229,8 +230,8 @@ void GuitarGraph::engine() {
break;
}
// Handle Start/Select keypresses
- if (ev.nav == input::CANCEL) toggleMenu();
- if (ev.nav == input::START && !m_menuOpen) ev.button = input::STARPOWER_BUTTON;
+ if (ev.nav == input::CANCEL) m_menu.toggle();
+ if (ev.nav == input::START && !menuOpen()) ev.button = input::STARPOWER_BUTTON;
//if (ev.type == input::Event::PRESS && ev.button > input::STARPOWER_BUTTON) {
//if (ev.button == 9) ev.button = input::STARPOWER_BUTTON; // Start works for GodMode
//else continue;
@@ -251,7 +252,7 @@ void GuitarGraph::engine() {
if (ev.type == input::Event::PRESS) m_pressed_anim[!m_drums + ev.button].setValue(1.0);
else if (ev.type == input::Event::PICK) m_pressed_anim[0].setValue(1.0);
// Menu keys
- if (m_menuOpen) {
+ if (menuOpen()) {
// Check first regular keys
if (ev.type == input::Event::PRESS && ev.button == 0 + m_drums) m_menu.action(1);
else if (ev.type == input::Event::PRESS && ev.button == 1 + m_drums) m_menu.action(-1);
@@ -1011,7 +1012,7 @@ void GuitarGraph::drawDrumfill(float tBeg, float tEnd) {
/// Draw popups and other info texts
void GuitarGraph::drawInfo(double time, double offsetX, Dimensions dimensions) {
// Draw info
- if (m_menuOpen) {
+ if (menuOpen()) {
drawMenu(offsetX);
} else {
float xcor = 0.35 * dimensions.w();
diff --git a/game/instrumentgraph.cc b/game/instrumentgraph.cc
index c999c24..ee789b6 100644
--- a/game/instrumentgraph.cc
+++ b/game/instrumentgraph.cc
@@ -9,7 +9,6 @@ InstrumentGraph::InstrumentGraph(Audio& audio, Song const& song, input::DevType
m_stream(),
m_cx(0.0, 0.2), m_width(0.5, 0.4),
m_menu(),
- m_menuOpen(true),
m_text(getThemePath("sing_timetxt.svg"), config["graphic/text_lod"].f()),
m_pads(),
m_correctness(0.0, 5.0),
@@ -27,7 +26,6 @@ InstrumentGraph::InstrumentGraph(Audio& audio, Song const& song, input::DevType
m_menuTheme.reset(new ThemeInstrumentMenu());
// Populate joining menu
- // TODO: Replace with option that actually does something
m_menu.add(MenuOption(_("Ready!"), _("Start performing!")));
// Guitar- / dancegraph specific options can be added in their constructors
}
@@ -43,13 +41,17 @@ void InstrumentGraph::setupPauseMenu() {
}
-void InstrumentGraph::toggleMenu(int dontforce) {
- if (dontforce == 0) { m_menuOpen = true; return; }
- if (m_menuOpen && !m_ready) {
+void InstrumentGraph::doUpdates() {
+ if (!menuOpen() && !m_ready) {
m_ready = true;
setupPauseMenu();
}
- m_menuOpen = !m_menuOpen;
+}
+
+
+void InstrumentGraph::toggleMenu(bool forceopen) {
+ if (forceopen) { m_menu.open(); return; }
+ m_menu.toggle();
}
diff --git a/game/instrumentgraph.hh b/game/instrumentgraph.hh
index 931ae07..31b5fe0 100644
--- a/game/instrumentgraph.hh
+++ b/game/instrumentgraph.hh
@@ -74,7 +74,8 @@ class InstrumentGraph {
virtual void changeTrack(int dir = 1) = 0;
virtual void changeDifficulty(int dir = 1) = 0;
- void toggleMenu(int dontforce = 1);
+ void doUpdates();
+ void toggleMenu(bool forceopen = false);
void togglePause(int) { m_audio.togglePause(); }
void restart(int) { /* TODO: Implement */ }
void quit(int) { ScreenManager::getSingletonPtr()->activateScreen("Songs"); }
@@ -82,7 +83,7 @@ class InstrumentGraph {
// General getters
bool ready() const { return m_ready; };
- bool menuOpen() const { return m_menuOpen; }
+ bool menuOpen() const { return m_menu.isOpen(); }
void position(double cx, double width) { m_cx.setTarget(cx); m_width.setTarget(width); }
unsigned stream() const { return m_stream; }
double correctness() const { return m_correctness.get(); }
@@ -110,7 +111,6 @@ class InstrumentGraph {
typedef std::vector<Popup> Popups;
Popups m_popups;
Menu m_menu;
- bool m_menuOpen;
// Shared functions for derived classes
void setupPauseMenu();
diff --git a/game/menu.cc b/game/menu.cc
index 13f0f7c..dde8d3e 100755
--- a/game/menu.cc
+++ b/game/menu.cc
@@ -62,6 +62,7 @@ void Menu::action(int dir) {
case MenuOption::OPEN_SUBMENU:
options = current->options;
current = options.begin();
+ m_level++;
break;
case MenuOption::CHANGE_VALUE:
if (current->value) {
@@ -74,9 +75,16 @@ void Menu::action(int dir) {
// Fall-through to closing
case MenuOption::CLOSE_SUBMENU:
// TODO: Handle more than one level of submenus
- // TODO: Closing root menu should signal that the menu is closing
+ if (m_level == 0) close();
+ else m_level--;
options = root_options;
current = options.begin();
break;
}
}
+
+void Menu::clear() {
+ options.clear();
+ root_options.clear();
+ current = options.end();
+}
diff --git a/game/menu.hh b/game/menu.hh
index ec0160c..ef89280 100755
--- a/game/menu.hh
+++ b/game/menu.hh
@@ -54,7 +54,7 @@ struct MainMenuOption {
/// Menu for selecting difficulty etc.
struct Menu {
/// constructor
- Menu(): current(options.end()) { }
+ Menu(): current(options.end()), m_open(true), m_level(0) { }
/// add a menu option
void add(MenuOption opt);
/// move the selection
@@ -62,9 +62,19 @@ struct Menu {
/// adjust the selected value
void action(int dir = 1);
/// clear items
- void clear() { options.clear(); }
+ void clear();
+
+ bool isOpen() const { return m_open; }
+ void open() { m_open = true; }
+ void close() { m_open = false; }
+ void toggle() { m_open = !m_open; }
MenuOptions options;
MenuOptions root_options;
MenuOptions::iterator current;
+
+ private:
+ bool m_open;
+ int m_level;
+
};
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 63d94f2..75a0e14 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -248,8 +248,8 @@ void ScreenSing::manageEvent(SDL_Event event) {
}
// Esc-key needs special handling, it is global pause
if (event.type == SDL_KEYDOWN && key == SDLK_ESCAPE && !m_audio.isPaused()) {
- for (Instruments::iterator it = m_instruments.begin(); it != m_instruments.end(); ++it) it->toggleMenu(1);
- for (Dancers::iterator it = m_dancers.begin(); it != m_dancers.end(); ++it) it->toggleMenu(1);
+ for (Instruments::iterator it = m_instruments.begin(); it != m_instruments.end(); ++it) it->toggleMenu(true);
+ for (Dancers::iterator it = m_dancers.begin(); it != m_dancers.end(); ++it) it->toggleMenu(true);
}
// Start button has special functions for skipping things (only in singing for now)
if (nav == input::START && m_only_singers_alive && !m_song->vocals.notes.empty() && !m_audio.isPaused()) {
|
|
From: Felix B. <fbe...@us...> - 2010-07-07 05:22:41
|
Module: performous
Branch: slowdown
Commit: 3fb16fc8c6c0605f89b9ba5c242742ac8f1a5f39
Author: Felix Bertram <fl...@be...>
Date: Mon Jul 5 22:47:14 2010 -0700
bugfix- fatal error for non-ogg files
---
game/audio.cc | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 18824d8..31b9534 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -82,17 +82,20 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
fadeout(fadeTime);
boost::shared_ptr<da::chain> ch(new da::chain());
for(std::map<std::string,std::string>::const_iterator it = filenames.begin() ; it != filenames.end() ; ++it ) {
- std::string f;
+ std::string f = it->second;
try {
- f = it->second;
if (speed != 100) {
// instead of real-time time-stretching we use previously created files
// best effects have been achieved with SBSMS library
// as used by Audacity's Sliding Time Scale/ Pitch Shift plugin
- std::string f2 = "-" + boost::lexical_cast<std::string>(speed) + ".ogg";
- f.replace(f.find(".ogg"), 4, f2);
- // std::cout << "loading time-stretched audio (" << f << ")" << std::endl;
+ size_t i = f.find_last_of(".");
+ if ((i == std::string::npos) || (f.length() - i > 5)) throw std::runtime_error("no file extension in \"" + f + "\"");
+ // for 75% speed a typical filename would be "song-75.ogg"
+ std::string f2 = "-" + boost::lexical_cast<std::string>(speed) + ".";
+ f.replace(i, 1, f2);
+
+ std::cout << "loading time-stretched audio (" << f << ")" << std::endl;
if (!boost::filesystem::exists(f)) throw std::runtime_error("time-stretched file \"" + f +"\" not found");
}
|
|
From: Tapio V. <aa...@us...> - 2010-07-06 21:43:56
|
Module: performous
Branch: master
Commit: cf96cf8b35d132aeb81f1a6fb4cc7205cdd09076
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jul 5 22:43:36 2010 +0300
Add enabled() to MidiDrums (in style of Webcam and Gettext) + fix some whitespace.
---
game/joystick.cc | 32 ++++++++++++++++----------------
game/joystick.hh | 2 ++
game/main.cc | 6 +-----
3 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/game/joystick.cc b/game/joystick.cc
index 8c1cf66..02d016d 100644
--- a/game/joystick.cc
+++ b/game/joystick.cc
@@ -22,30 +22,30 @@ input::MidiDrums::MidiDrums(): stream(pm::findDevice(true, config["system/midi_i
static const int DRUM3_BLUE = 3; // low tom/ ride cymbal
static const int DRUM4_GREEN = 4; // low floor tom/ crash cymbal
- map[35] = DRUM0_ORANGE; // 35 - Acoustic Bass Drum
+ map[35] = DRUM0_ORANGE; // 35 - Acoustic Bass Drum
map[36] = DRUM0_ORANGE; // 36 - Bass Drum 1 *)
- map[37] = DRUM1_RED; // 37 - Side Stick
- map[38] = DRUM1_RED; // 38 - Acoustic Snare *)
- // 39 - Hand Clap
- map[40] = DRUM1_RED; // 40 - Electric Snare
+ map[37] = DRUM1_RED; // 37 - Side Stick
+ map[38] = DRUM1_RED; // 38 - Acoustic Snare *)
+ // 39 - Hand Clap
+ map[40] = DRUM1_RED; // 40 - Electric Snare
map[41] = DRUM4_GREEN; // 41 - Low Floor Tom *)
- map[42] = DRUM2_YELLOW; // 42 - Closed Hi-Hat
- // 43 - High Floor Tom
+ map[42] = DRUM2_YELLOW; // 42 - Closed Hi-Hat
+ // 43 - High Floor Tom
// map[44] = DRUM2_YELLOW; // 44 - Pedal Hi-Hat *) - ignore this for playability!
map[45] = DRUM3_BLUE; // 45 - Low Tom *)
map[46] = DRUM2_YELLOW; // 46 - Open Hi-Hat *)
- // 47 - Low-Mid Tom
+ // 47 - Low-Mid Tom
map[48] = DRUM2_YELLOW; // 48 - Hi-Mid Tom *)
map[49] = DRUM4_GREEN; // 49 - Crash Cymbal 1 *)
// 50 - High Tom
map[51] = DRUM3_BLUE; // 51 - Ride Cymbal 1 *)
// 52 - Chinese Cymbal
- // 53 - Ride Bell
- // 54 - Tambourine
- // 55 - Splash Cymbal
- // 56 - Cowbell
- map[57] = DRUM4_GREEN; // 57 - Crash Cymbal 2
- // 58 - Vibraslap
+ // 53 - Ride Bell
+ // 54 - Tambourine
+ // 55 - Splash Cymbal
+ // 56 - Cowbell
+ map[57] = DRUM4_GREEN; // 57 - Crash Cymbal 2
+ // 58 - Vibraslap
map[59] = DRUM3_BLUE; // 59 - Ride Cymbal 2
// 60 - Hi Bongo
// 61 - Low Bongo
@@ -56,7 +56,7 @@ input::MidiDrums::MidiDrums(): stream(pm::findDevice(true, config["system/midi_i
// 66 - Low Timbale
// 67 - High Agogo
// 68 - Low Agogo
- // 69 - Cabasa
+ // 69 - Cabasa
// 70 - Maracas
// 71 - Short Whistle
// 72 - Long Whistle
@@ -91,7 +91,7 @@ void input::MidiDrums::process() {
unsigned char note = ev.message >> 8;
unsigned char vel = ev.message >> 16;
#if 0
- // it is IMHO not a good idea to filter on the channel.
+ // it is IMHO not a good idea to filter on the channel.
// code snippet left here for visibility
unsigned char chan = ev.message & 0x0F;
if (chan != 0x09) continue; // only accept channel 10 (percussion)
diff --git a/game/joystick.hh b/game/joystick.hh
index ab12136..d8086ae 100644
--- a/game/joystick.hh
+++ b/game/joystick.hh
@@ -160,6 +160,7 @@ namespace input {
#ifdef USE_PORTMIDI
class MidiDrums {
public:
+ static bool enabled() { return true; }
MidiDrums();
void process();
private:
@@ -172,6 +173,7 @@ namespace input {
#else
class MidiDrums {
public:
+ static bool enabled() { return false; }
MidiDrums() {};
void process() {};
private:
diff --git a/game/main.cc b/game/main.cc
index e577384..0d1f585 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -406,11 +406,7 @@ void outputOptionalFeatureStatus() {
std::cout << " Internationalization: " <<
(Gettext::enabled() ? "Enabled" : "Disabled")
<< std::endl << " MIDI I/O: " <<
- #ifdef USE_PORTMIDI
- "Enabled"
- #else
- "Disabled"
- #endif
+ (input::MidiDrums::enabled() ? "Enabled" : "Disabled")
<< std::endl << " Webcam support: " <<
(Webcam::enabled() ? "Enabled" : "Disabled")
<< std::endl;
|
|
From: Tapio V. <aa...@us...> - 2010-07-06 21:41:38
|
Module: performous Branch: joinmenu Commit: 0e80e0d08d39bfbede80ac794e4166297b48f745 Author: Tapio Vierros <tap...@gm...> Date: Wed Jul 7 00:34:52 2010 +0300 Rewrite menu system. * Much more generic - No more member function pointers to InstrumentGraph - Use pointers to ConfigItems instead * Introduce submenu concept - Only one additional level for now * Introduce "set specific value and exit submenu" option type * "Change value" option type still available (for numeric ConfigItems) * Theme is outside of Menu structure * Breaks functionality for now - Exiting not root menu not implemented - Proper difficulty/track selection + pause menu population N/A - Some ConfigItems needs to be added to InstrumentGraph --- game/configuration.cc | 10 +++++ game/configuration.hh | 4 ++ game/dancegraph.cc | 19 +++++++--- game/guitargraph.cc | 19 +++++++--- game/instrumentgraph.cc | 29 +++++++++------- game/instrumentgraph.hh | 4 ++- game/menu.cc | 86 +++++++++++++++++++++++++++++++--------------- game/menu.hh | 63 +++++++++++++++++----------------- 8 files changed, 148 insertions(+), 86 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2010-07-06 08:44:28
|
Module: performous
Branch: master
Commit: 2c2aeaa2abee6a18e173599371db5b15778df3c7
Author: Vincent Le Ligeour <yo...@us...>
Date: Tue Jul 6 10:44:13 2010 +0200
Added new theme file to windows NSI
---
win32/setup.nsi | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/win32/setup.nsi b/win32/setup.nsi
index 9c4c359..220d217 100644
--- a/win32/setup.nsi
+++ b/win32/setup.nsi
@@ -226,6 +226,7 @@ Section "SezionePrincipale" SEC01
File "${FILES_PATH}\themes\default\songs_order.svg"
File "${FILES_PATH}\themes\default\songs_song.svg"
File "${FILES_PATH}\themes\default\star.svg"
+ File "${FILES_PATH}\themes\default\star_glow.svg"
File "${FILES_PATH}\themes\default\tail.svg"
File "${FILES_PATH}\themes\default\tail_drumfill.svg"
File "${FILES_PATH}\themes\default\tail_glow.svg"
@@ -285,6 +286,7 @@ Section Uninstall
Delete "$INSTDIR\themes\default\tail_glow.svg"
Delete "$INSTDIR\themes\default\tail_drumfill.svg"
Delete "$INSTDIR\themes\default\tail.svg"
+ Delete "$INSTDIR\themes\default\star_glow.svg"
Delete "$INSTDIR\themes\default\star.svg"
Delete "$INSTDIR\themes\default\songs_song.svg"
Delete "$INSTDIR\themes\default\songs_order.svg"
|
|
From: Felix B. <fbe...@us...> - 2010-07-05 23:10:56
|
Module: performous
Branch: master
Commit: d6d3a4991e7d1735c8242aca92893afe626cf99a
Author: Felix Bertram <fl...@be...>
Date: Mon Jul 5 16:08:32 2010 -0700
bugfix for multiple audio devices in config
when multiple audio devices where specified in the config file, the code did not stop to use a device that was successfully opened. This patch fixes the behavior and stops at the first devices that can be opened.
---
game/main.cc | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/game/main.cc b/game/main.cc
index 91aed77..e577384 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -145,6 +145,9 @@ void audioSetup(Capture& capture, Audio& audio) {
if (channels != 2) throw std::runtime_error("Only stereo playback is supported, error in pdev=" + *it);
try {
audio.open(devstr, rate, frames);
+ // when we get here, we have successfully opened a device.
+ // let's use it then!
+ break;
} catch (std::exception const& e) {
std::cerr << "Playback device pdev=" << *it << " failed and will be ignored:\n " << e.what() << std::endl;
}
|
|
From: Felix B. <fbe...@us...> - 2010-07-05 20:17:14
|
Module: performous
Branch: master
Commit: 6bb7de2655d6ab9039b7ae7a538548f31a3e5595
Author: Felix Bertram <fl...@be...>
Date: Mon Jul 5 12:50:47 2010 -0700
Revert "Slowdown play"
create new features in separate branch
This reverts commit c783bf544100b9501830fd34c256ac9e30324b8a.
---
game/audio.cc | 44 +++++++++-----------------------------------
game/audio.hh | 7 ++-----
game/guitargraph.cc | 4 +---
game/main.cc | 2 --
game/screen_sing.cc | 8 ++------
game/screen_sing.hh | 1 -
6 files changed, 14 insertions(+), 52 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 18824d8..ae4acfb 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -5,7 +5,6 @@
#include <libda/fft.hpp> // For M_PI
#include <cmath>
#include <iostream>
-#include <boost/filesystem.hpp>
struct SampleStream {
SampleStream(boost::shared_ptr<FFmpeg> const& mpeg): m_mpeg(mpeg) {}
@@ -76,39 +75,19 @@ void Audio::play(Sample const& s, std::string const& volumeSetting) {
m_mixer.add(da::shared_ref(acc));
}
-void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool preview, double fadeTime, double startPos, int speed) {
+void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool preview, double fadeTime, double startPos) {
if (!isOpen()) return;
da::lock_holder l = m_mixer.lock();
fadeout(fadeTime);
boost::shared_ptr<da::chain> ch(new da::chain());
for(std::map<std::string,std::string>::const_iterator it = filenames.begin() ; it != filenames.end() ; ++it ) {
- std::string f;
try {
- f = it->second;
- if (speed != 100) {
- // instead of real-time time-stretching we use previously created files
- // best effects have been achieved with SBSMS library
- // as used by Audacity's Sliding Time Scale/ Pitch Shift plugin
- std::string f2 = "-" + boost::lexical_cast<std::string>(speed) + ".ogg";
- f.replace(f.find(".ogg"), 4, f2);
- // std::cout << "loading time-stretched audio (" << f << ")" << std::endl;
-
- if (!boost::filesystem::exists(f)) throw std::runtime_error("time-stretched file \"" + f +"\" not found");
- }
-
- boost::shared_ptr<Stream> s(new Stream(f, m_rs.rate()));
+ boost::shared_ptr<Stream> s(new Stream(it->second, m_rs.rate()));
m_streams[it->first] = s;
ch->add(da::shared_ref(s));
s->seek(startPos);
} catch (std::runtime_error& e) {
- if (speed != 100) {
- // in case time-stretching failed let's retry at normal speed
- // TODO: we could also auto-create time-stretched files here
- playMusic(filenames, preview, fadeTime, startPos, 100);
- return;
- }
- // in case we are at normal speed we skip this file and try to continue
- std::cerr << "Error loading " << f << " (" << e.what() << ")" << std::endl;
+ std::cerr << "Error loading " << it->second << " (" << e.what() << ")" << std::endl;
continue;
}
}
@@ -117,14 +96,12 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
ch->add(boost::ref(m_volume));
m_mixer.fadein(da::shared_ref(ch), fadeTime, startPos);
if (!preview) pause(false);
-
- m_speed = speed;
}
-void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos, int speed) {
+void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
std::map<std::string,std::string> tmp;
tmp["unidentified"] = filename;
- playMusic(tmp, preview, fadeTime, startPos, speed);
+ playMusic(tmp, preview, fadeTime, startPos);
}
void Audio::stopMusic() {
@@ -143,13 +120,12 @@ void Audio::fadeout(double fadeTime) {
double Audio::getPosition() const {
da::lock_holder l = m_mixer.lock();
- // only the audio slows down; the game still uses original time base
- return m_streams.empty() ? getNaN() : m_streams.begin()->second->pos() * m_speed/100.0;
+ return m_streams.empty() ? getNaN() : m_streams.begin()->second->pos();
}
double Audio::getLength() const {
da::lock_holder l = m_mixer.lock();
- return m_streams.empty() ? getNaN() : m_streams.begin()->second->duration() * m_speed/100.0;
+ return m_streams.empty() ? getNaN() : m_streams.begin()->second->duration();
}
bool Audio::isPlaying() const {
@@ -157,16 +133,14 @@ bool Audio::isPlaying() const {
return m_streams.empty() ? false : !m_streams.begin()->second->eof();
}
-void Audio::seek(double offset2) {
- double offset = offset2 * 100.0/m_speed;
+void Audio::seek(double offset) {
da::lock_holder l = m_mixer.lock();
for(std::map<std::string,boost::shared_ptr<Stream> >::iterator it = m_streams.begin() ; it != m_streams.end() ; ++it)
it->second->seek(clamp(it->second->pos() + offset, 0.0, it->second->duration()));
pause(false);
}
-void Audio::seekPos(double pos2) {
- double pos = pos2 * 100.0/m_speed;
+void Audio::seekPos(double pos) {
da::lock_holder l = m_mixer.lock();
for(std::map<std::string,boost::shared_ptr<Stream> >::iterator it = m_streams.begin() ; it != m_streams.end() ; ++it)
it->second->seek(pos);
diff --git a/game/audio.hh b/game/audio.hh
index d441cb1..e4f701f 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -94,9 +94,9 @@ class Audio {
* @param fadeTime time to fade
* @param startPos starting position
*/
- void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.5, double startPos = -0.2, int speed = 100);
+ void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.5, double startPos = -0.2);
/// plays a list of songs
- void playMusic(std::map<std::string,std::string> const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = -0.2, int speed = 100);
+ void playMusic(std::map<std::string,std::string> const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = -0.2);
/// plays a sample
void play(Sample const& s, std::string const& volumeSetting);
/// get pause status
@@ -107,8 +107,6 @@ class Audio {
void fadeout(double time = 1.0);
/** Get the length of the currently playing song, in seconds. **/
double getLength() const;
- /// return current speed
- int getSpeed() {return m_speed;}
/**
* This methods seek forward in the stream (backwards if
* argument is negative), and continues playing.
@@ -139,6 +137,5 @@ class Audio {
std::string m_volumeSetting;
da::mixer m_mixer;
std::map<std::string,boost::shared_ptr<Stream> > m_streams;
- int m_speed;
};
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 0fdf6aa..0be7a41 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -185,9 +185,7 @@ bool GuitarGraph::difficulty(Difficulty level) {
/// Core engine
void GuitarGraph::engine() {
double time = m_audio.getPosition();
- // need to compensate for speed as well. When playing at half speed,
- // 1 second from getPosition is actually two seconds in real time
- time -= config["audio/controller_delay"].f() * m_audio.getSpeed()/100.0;
+ time -= config["audio/controller_delay"].f();
// Handle key markers
if (!m_drums) {
for (int i = 0; i < m_pads; ++i) {
diff --git a/game/main.cc b/game/main.cc
index 03da057..91aed77 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -145,8 +145,6 @@ void audioSetup(Capture& capture, Audio& audio) {
if (channels != 2) throw std::runtime_error("Only stereo playback is supported, error in pdev=" + *it);
try {
audio.open(devstr, rate, frames);
- // when we get here, we have successfully opened a device. let's use it!
- break;
} catch (std::exception const& e) {
std::cerr << "Playback device pdev=" << *it << " failed and will be ignored:\n " << e.what() << std::endl;
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 0b52e85..dd822f3 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -31,7 +31,6 @@ namespace {
void ScreenSing::enter() {
//m_practmode = true; // un-comment this line to play with practice mode. temporary, of course!
- m_speed = 75; // 75% slow-down; falls back to 100% if time-stretch files are not found. temporary, of course!
ScreenManager* sm = ScreenManager::getSingletonPtr();
sm->flashMessage(_("Loading song..."), 0.0, 1.0, 0.5);
sm->drawFlashMessage(); sm->window().swap(); // Make loading message show
@@ -86,7 +85,6 @@ void ScreenSing::enter() {
theme->timer.dimensions.screenTop(0.5 * m_progress->dimensions.h());
boost::ptr_vector<Analyzer>& analyzers = m_capture.analyzers();
m_layout_singer.reset(new LayoutSinger(m_song->vocals, m_database, theme));
-
// Load instrument and dance tracks
{
int type = 0; // 0 for dance, 1 for guitars, 2 for drums
@@ -110,7 +108,7 @@ void ScreenSing::enter() {
}
// Startup delay for instruments is longer than for singing only
double setup_delay = (m_instruments.empty() && m_dancers.empty() ? -1.0 : -8.0);
- m_audio.playMusic(m_song->music, false, 0.0, setup_delay, m_speed);
+ m_audio.playMusic(m_song->music, false, 0.0, setup_delay);
m_engine.reset(new Engine(m_audio, m_song->vocals, analyzers.begin(), analyzers.end(), m_database));
}
@@ -319,9 +317,7 @@ void ScreenSing::draw() {
// Get the time in the song
double length = m_audio.getLength();
double time = m_audio.getPosition();
- // need to compensate for speed as well. When playing at half speed,
- // 1 second from getPosition is actually two seconds in real time
- time -= config["audio/video_delay"].f() * m_audio.getSpeed()/100.0;
+ time -= config["audio/video_delay"].f();
double songPercent = clamp(time / length);
// Rendering starts
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index 16cff8e..c743877 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -93,6 +93,5 @@ class ScreenSing: public Screen {
AnimValue m_quitTimer;
bool m_only_singers_alive;
bool m_practmode;
- int m_speed; // speed in percent, 100 for normal, 50 for half
};
|
|
From: Yoda-JM <yo...@us...> - 2010-07-05 19:27:06
|
Module: performous
Branch: portaudio
Commit: 7b5d9e1559f236a44c38e8c82675f1d627423d94
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 21:26:46 2010 +0200
Added note synth to audio code
---
game/audio.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
game/audio.hh | 2 +-
2 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index ac93f15..1cb771a 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -102,6 +102,36 @@ struct Sample {
}
};
+struct Synth {
+ private:
+ Notes m_notes;
+ double srate; ///< Sample rate
+ public:
+ Synth(Notes const& notes, unsigned int sr) : m_notes(notes), srate(sr) {};
+ void operator()(float* begin, float* end, double position) {
+ static double phase = 0.0;
+ for (float *i = begin; i < end; ++i) *i *= 0.3; // Decrease music volume
+
+ std::vector<float> mixbuf(end - begin);
+ Notes::const_iterator it = m_notes.begin();
+
+ while (it != m_notes.end() && it->end < position) ++it;
+ if (it == m_notes.end() || it->type == Note::SLEEP || it->begin > position) { phase = 0.0; return; }
+ int note = it->note % 12;
+ double d = (note + 1) / 13.0;
+ double freq = MusicalScale().getNoteFreq(note + 12);
+ double value = 0.0;
+ // Synthesize tones
+ for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
+ if (i % 2 == 0) {
+ value = d * 0.2 * std::sin(phase) + 0.2 * std::sin(2 * phase) + (1.0 - d) * 0.2 * std::sin(4 * phase);
+ phase += 2.0 * M_PI * freq / srate;
+ }
+ begin[i] += value;
+ }
+ }
+};
+
struct Command {
enum { TRACK_FADE, SAMPLE_RESET } type;
@@ -112,6 +142,8 @@ struct Command {
struct Output {
boost::mutex mutex;
boost::mutex samples_mutex;
+ boost::mutex synth_mutex;
+ std::auto_ptr<Synth> synth;
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
boost::ptr_map<std::string, Sample> samples;
@@ -167,6 +199,13 @@ struct Output {
}
}
}
+ // Mix synth if available (should be done at the end)
+ {
+ boost::mutex::scoped_try_lock l(synth_mutex, boost::defer_lock);
+ if(l.try_lock() && synth.get() && !playing.empty()) {
+ (*synth.get())(begin, end, playing[0].pos());
+ }
+ }
}
};
@@ -326,5 +365,11 @@ void Audio::streamFade(std::string track, double fadeLevel) {
o.commands.push_back(cmd);
}
+void Audio::toggleSynth(Notes const& notes) {
+ Output& o = self->output;
+ boost::mutex::scoped_lock l(o.synth_mutex);
+ o.synth.get() ? o.synth.reset() : o.synth.reset(new Synth(notes, getSR()));
+}
+
boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
diff --git a/game/audio.hh b/game/audio.hh
index 1087c8f..dab6770 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -54,7 +54,7 @@ public:
void togglePause() { pause(!isPaused()); }
void pause(bool state = true);
bool isPaused() const;
- void toggleSynth(Notes const&) { /*m_notes = (m_notes ? NULL : ¬es); */} ///< toggles synth playback
+ void toggleSynth(Notes const&); ///< toggles synth playback
/// Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0.
void streamFade(std::string track, double volume);
double getSR() const { return 48000.0; }
|
|
From: Tapio V. <aa...@us...> - 2010-07-05 18:51:35
|
Module: performous Branch: master Commit: d51a1ea094c57ed0357791e70e253e498606f9f8 Author: Tapio Vierros <tap...@gm...> Date: Mon Jul 5 21:46:14 2010 +0300 Refactor song parsers. * Move long constructor to a new .cc file. * Move duplicate helper functions to one place. * Use Boost for case conversions. --- game/songparser-ini.cc | 16 +----- game/songparser-sm.cc | 31 +---------- game/songparser-txt.cc | 23 +-------- game/songparser.cc | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ game/songparser.hh | 111 +++++---------------------------------- 5 files changed, 157 insertions(+), 161 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2010-07-05 18:51:34
|
Module: performous Branch: master Commit: 2e763d3921ad673cdc0e9ae48b7ec1b7429c4dab Author: Tapio Vierros <tap...@gm...> Date: Mon Jul 5 20:42:11 2010 +0300 Every singer now gets colored stars individually. --- game/notegraph.cc | 38 ++++---- game/notegraph.hh | 1 + game/notes.hh | 6 +- game/player.cc | 7 +- themes/default/star_glow.svg | 209 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 240 insertions(+), 21 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2010-07-05 17:59:10
|
Module: performous
Branch: portaudio
Commit: 34aaed0a09c83565b5481f6744cb3ba0f7c4c486
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 19:58:53 2010 +0200
Implemented audio volume
---
game/audio.cc | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 67b1ec9..ac93f15 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -45,7 +45,7 @@ public:
if (fadeLevel <= 0.0) return false;
if (fadeLevel > 1.0) { fadeLevel = 1.0; fadeRate = 0.0; }
}
- begin[i] += mixbuf[i] * fadeLevel;
+ begin[i] += mixbuf[i] * fadeLevel * static_cast<float>(m_preview ? config["audio/preview_volume"].i() : config["audio/music_volume"].i())/100.0;
}
return !eof;
}
@@ -92,7 +92,7 @@ struct Sample {
eof = true;
}
for (size_t i = 0, iend = end - begin; i != iend; ++i) {
- begin[i] += mixbuf[i];
+ begin[i] += mixbuf[i] * static_cast<float>(config["audio/fail_volume"].i())/100.0;
}
m_pos += end - begin;
}
|
|
From: Yoda-JM <yo...@us...> - 2010-07-05 17:09:03
|
Module: performous
Branch: portaudio
Commit: 7bc30cc15ec978b178cca13be2892401ba7c868d
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 19:08:46 2010 +0200
Fixed audio sample thread model
---
game/audio.cc | 45 ++++++++++++++++++++++++++++-----------------
1 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 97feaaf..67b1ec9 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -20,11 +20,12 @@ class Music {
Tracks tracks; ///< Audio decoders
double srate; ///< Sample rate
int64_t m_pos; ///< Current sample position
+ bool m_preview;
public:
double fadeLevel;
double fadeRate;
typedef std::map<std::string,std::string> Files;
- Music(Files const& filenames, unsigned int sr): srate(sr), m_pos(), fadeLevel(), fadeRate() {
+ Music(Files const& filenames, unsigned int sr, bool preview): srate(sr), m_pos(), m_preview(preview), fadeLevel(), fadeRate() {
for (Files::const_iterator it = filenames.begin(), end = filenames.end(); it != end; ++it) {
tracks.insert(it->first, std::auto_ptr<Track>(new Track(it->second, sr)));
}
@@ -73,15 +74,14 @@ public:
}
};
-// rename to Sample once totally implemented
-struct SampleNew {
+struct Sample {
private:
unsigned int srate;
double m_pos;
FFmpeg mpeg;
bool eof;
public:
- SampleNew(std::string const& filename, unsigned sr) : srate(sr), m_pos(), mpeg(false, true, filename, sr), eof(true) { }
+ Sample(std::string const& filename, unsigned sr) : srate(sr), m_pos(), mpeg(false, true, filename, sr), eof(true) { }
void operator()(float* begin, float* end) {
if(eof) {
// No more data to play in this sample
@@ -104,16 +104,17 @@ struct SampleNew {
struct Command {
- enum { TRACK_FADE } type;
+ enum { TRACK_FADE, SAMPLE_RESET } type;
std::string track;
double fadeLevel;
};
struct Output {
boost::mutex mutex;
+ boost::mutex samples_mutex;
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
- boost::ptr_map<std::string, SampleNew> samples;
+ boost::ptr_map<std::string, Sample> samples;
std::vector<Command> commands;
volatile bool paused;
Output(): paused(false) {}
@@ -132,6 +133,11 @@ struct Output {
case Command::TRACK_FADE:
if (!playing.empty()) playing[0].trackFade(cmd.track, cmd.fadeLevel);
break;
+ case Command::SAMPLE_RESET:
+ boost::ptr_map<std::string, Sample>::iterator it = samples.find(cmd.track);
+ if (it != samples.end())
+ it->second->reset();
+ break;
}
}
commands.clear();
@@ -152,9 +158,14 @@ struct Output {
++i;
}
// Mix in the samples currently playing
- for(boost::ptr_map<std::string, SampleNew>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
- boost::mutex::scoped_try_lock l(mutex);
- (*it->second)(begin, end);
+ {
+ // samples should not be created/destroyed on the fly
+ boost::mutex::scoped_try_lock l(samples_mutex, boost::defer_lock);
+ if(l.try_lock()) {
+ for(boost::ptr_map<std::string, Sample>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
+ (*it->second)(begin, end);
+ }
+ }
}
}
};
@@ -226,19 +237,19 @@ bool Audio::isOpen() const {
}
void Audio::loadSample(std::string const& streamId, std::string const& filename) {
- boost::mutex::scoped_lock l(self->output.mutex);
- self->output.samples.insert(streamId, std::auto_ptr<SampleNew>(new SampleNew(filename, getSR())));
+ boost::mutex::scoped_lock l(self->output.samples_mutex);
+ self->output.samples.insert(streamId, std::auto_ptr<Sample>(new Sample(filename, getSR())));
}
void Audio::playSample(std::string const& streamId) {
- boost::mutex::scoped_lock l(self->output.mutex);
- boost::ptr_map<std::string, SampleNew>::iterator it = self->output.samples.find(streamId);
- if (it == self->output.samples.end()) throw std::runtime_error("Cannot play sample : " + streamId);
- it->second->reset();
+ Output& o = self->output;
+ boost::mutex::scoped_lock l(o.mutex);
+ Command cmd = { Command::SAMPLE_RESET, streamId, 0.0 };
+ o.commands.push_back(cmd);
}
void Audio::unloadSample(std::string const& streamId) {
- boost::mutex::scoped_lock l(self->output.mutex);
+ boost::mutex::scoped_lock l(self->output.samples_mutex);
self->output.samples.erase(streamId);
}
@@ -246,7 +257,7 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
Output& o = self->output;
boost::mutex::scoped_lock l(o.mutex);
o.disposing.clear(); // Delete disposed streams
- o.preloading.reset(new Music(filenames, getSR()));
+ o.preloading.reset(new Music(filenames, getSR(), preview));
Music& m = *o.preloading.get();
m.seek(startPos);
m.fadeRate = 1.0 / getSR() / fadeTime;
|
|
From: Yoda-JM <yo...@us...> - 2010-07-05 14:02:51
|
Module: performous
Branch: portaudio
Commit: 3e2ae0eeceb114895884c11851f818fead791188
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 16:02:29 2010 +0200
Moved all samples loading to init
---
game/audio.cc | 4 ++--
game/guitargraph.cc | 31 +++++++++++++------------------
game/guitargraph.hh | 2 +-
game/main.cc | 14 ++++++++++++++
game/screen_practice.cc | 20 +++++++-------------
game/screen_practice.hh | 2 +-
libs/libda/include/libda/portaudio.hpp | 4 ++--
7 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 0d9b7a5..97feaaf 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -167,10 +167,10 @@ struct Device {
portaudio::Stream stream;
std::vector<Analyzer*> mics;
Output* outptr;
-
+
Device(unsigned int in, unsigned int out, double rate, std::string dev):
in(in), out(out), rate(rate), dev(dev),
- stream(*this, in ? portaudio::Params().channelCount(in).device(dev, true) : NULL, out ? portaudio::Params().channelCount(out).device(dev, false) : NULL, rate)
+ stream(*this, in ? portaudio::Params().channelCount(in).device(dev, true) : (const PaStreamParameters*)NULL, (out ? portaudio::Params().channelCount(out).device(dev, false) : (const PaStreamParameters*)NULL), rate)
{
mics.resize(in);
}
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index d9e3383..86b5e32 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -100,25 +100,20 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
// Score calculator (TODO a better one)
m_scoreText.reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
m_streakText.reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
- // Load fail sounds
if (m_drums) {
- m_samples.push_back(std::make_pair("drum bass", getPath("sounds/drum_bass.ogg")));
- m_samples.push_back(std::make_pair("drum snare", getPath("sounds/drum_snare.ogg")));
- m_samples.push_back(std::make_pair("drum hi-hat", getPath("sounds/drum_hi-hat.ogg")));
- m_samples.push_back(std::make_pair("drum tom1", getPath("sounds/drum_tom1.ogg")));
- m_samples.push_back(std::make_pair("drum cymbal", getPath("sounds/drum_cymbal.ogg")));
- //m_samples.push_back(std::make_pair("drum tom2", getPath("sounds/drum_tom2.ogg")));
+ m_samples.push_back("drum bass");
+ m_samples.push_back("drum snare");
+ m_samples.push_back("drum hi-hat");
+ m_samples.push_back("drum tom1");
+ m_samples.push_back("drum cymbal");
+ //m_samples.push_back("drum tom2");
} else {
- m_samples.push_back(std::make_pair("guitar fail1", getPath("sounds/guitar_fail1.ogg")));
- m_samples.push_back(std::make_pair("guitar fail2", getPath("sounds/guitar_fail2.ogg")));
- m_samples.push_back(std::make_pair("guitar fail3", getPath("sounds/guitar_fail3.ogg")));
- m_samples.push_back(std::make_pair("guitar fail4", getPath("sounds/guitar_fail4.ogg")));
- m_samples.push_back(std::make_pair("guitar fail5", getPath("sounds/guitar_fail5.ogg")));
- m_samples.push_back(std::make_pair("guitar fail6", getPath("sounds/guitar_fail6.ogg")));
- }
- // Warning the sample are shared between Guitargraphs, do not unload them
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.loadSample(m_samples[i].first, m_samples[i].second);
+ m_samples.push_back("guitar fail1");
+ m_samples.push_back("guitar fail2");
+ m_samples.push_back("guitar fail3");
+ m_samples.push_back("guitar fail4");
+ m_samples.push_back("guitar fail5");
+ m_samples.push_back("guitar fail6");
}
for (int i = 0; i < 6; ++i) m_pressed_anim[i].setRate(5.0);
for (int i = 0; i < 5; ++i) m_holds[i] = 0;
@@ -409,7 +404,7 @@ void GuitarGraph::fail(double time, int fret) {
// Reduce points and play fail sample only when GodMode is deactivated
m_events.push_back(Event(time, 0, fret));
if (fret < 0) fret = std::rand();
- m_audio.playSample(m_samples[unsigned(fret) % m_samples.size()].first);
+ m_audio.playSample(m_samples[unsigned(fret) % m_samples.size()]);
// remove equivalent of 1 perfect hit for every note
// kids tend to play a lot of extra notes just for the fun of it.
// need to make sure they don't end up with a score of zero
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index 9e53408..0a41db2 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -88,7 +88,7 @@ class GuitarGraph: public InstrumentGraph {
glutil::Color m_neckglowColor;
Object3d m_fretObj; /// 3d object for regular note
Object3d m_tappableObj; /// 3d object for the HOPO note cap
- std::vector<std::pair<std::string, std::string> > m_samples; /// sound effects
+ std::vector<std::string> m_samples; /// sound effects
boost::scoped_ptr<Texture> m_neck; /// necks
boost::scoped_ptr<SvgTxtThemeSimple> m_scoreText;
boost::scoped_ptr<SvgTxtThemeSimple> m_streakText;
diff --git a/game/main.cc b/game/main.cc
index fcc41ec..f466381 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -117,6 +117,20 @@ void mainLoop(std::string const& songlist) {
boost::scoped_ptr<input::MidiDrums> midiDrums;
// TODO: Proper error handling...
try { midiDrums.reset(new input::MidiDrums); } catch (std::runtime_error&) {}
+ // Load audio samples
+ audio.loadSample("drum bass", getPath("sounds/drum_bass.ogg"));
+ audio.loadSample("drum snare", getPath("sounds/drum_snare.ogg"));
+ audio.loadSample("drum hi-hat", getPath("sounds/drum_hi-hat.ogg"));
+ audio.loadSample("drum tom1", getPath("sounds/drum_tom1.ogg"));
+ audio.loadSample("drum cymbal", getPath("sounds/drum_cymbal.ogg"));
+ //audio.loadSample("drum tom2", getPath("sounds/drum_tom2.ogg"));
+ audio.loadSample("guitar fail1", getPath("sounds/guitar_fail1.ogg"));
+ audio.loadSample("guitar fail2", getPath("sounds/guitar_fail2.ogg"));
+ audio.loadSample("guitar fail3", getPath("sounds/guitar_fail3.ogg"));
+ audio.loadSample("guitar fail4", getPath("sounds/guitar_fail4.ogg"));
+ audio.loadSample("guitar fail5", getPath("sounds/guitar_fail5.ogg"));
+ audio.loadSample("guitar fail6", getPath("sounds/guitar_fail6.ogg"));
+ // Load screens
sm.addScreen(new ScreenIntro("Intro", audio));
sm.addScreen(new ScreenSongs("Songs", audio, songs, database));
sm.addScreen(new ScreenSing("Sing", audio, database, backgrounds));
diff --git a/game/screen_practice.cc b/game/screen_practice.cc
index d0b2896..d48afd1 100644
--- a/game/screen_practice.cc
+++ b/game/screen_practice.cc
@@ -18,21 +18,15 @@ void ScreenPractice::enter() {
m_vumeters.push_back(b = new ProgressBar(getThemePath("vumeter_bg.svg"), getThemePath("vumeter_fg.svg"), ProgressBar::VERTICAL, 0.136, 0.023));
b->dimensions.screenBottom().left(-0.4 + i * 0.2).fixedWidth(0.04);
}
- m_samples.push_back(std::make_pair("drum bass", getPath("sounds/drum_bass.ogg")));
- m_samples.push_back(std::make_pair("drum snare", getPath("sounds/drum_snare.ogg")));
- m_samples.push_back(std::make_pair("drum hi-hat", getPath("sounds/drum_hi-hat.ogg")));
- m_samples.push_back(std::make_pair("drum tom1", getPath("sounds/drum_tom1.ogg")));
- m_samples.push_back(std::make_pair("drum cymbal", getPath("sounds/drum_cymbal.ogg")));
- //m_samples.push_back(std::make_pair("drum tom2", getPath("sounds/drum_tom2.ogg")));
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.loadSample(m_samples[i].first, m_samples[i].second);
- }
+ m_samples.push_back("drum bass");
+ m_samples.push_back("drum snare");
+ m_samples.push_back("drum hi-hat");
+ m_samples.push_back("drum tom1");
+ m_samples.push_back("drum cymbal");
+ //m_samples.push_back("drum tom2");
}
void ScreenPractice::exit() {
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.unloadSample(m_samples[i].first);
- }
m_vumeters.clear();
m_samples.clear();
theme.reset();
@@ -47,7 +41,7 @@ void ScreenPractice::manageEvent(SDL_Event event) {
else if (event.type == SDL_JOYBUTTONDOWN // Play drum sounds here
&& input::detail::devices[event.jbutton.which].type_match(input::DRUMS)) {
int b = input::buttonFromSDL(input::detail::devices[event.jbutton.which].type(), event.jbutton.button);
- if (b != -1) m_audio.playSample(m_samples[unsigned(b) % m_samples.size()].first);
+ if (b != -1) m_audio.playSample(m_samples[unsigned(b) % m_samples.size()]);
}
}
diff --git a/game/screen_practice.hh b/game/screen_practice.hh
index 2d472d2..f8156f5 100644
--- a/game/screen_practice.hh
+++ b/game/screen_practice.hh
@@ -23,7 +23,7 @@ class ScreenPractice : public Screen {
private:
Audio& m_audio;
- std::vector<std::pair<std::string, std::string> > m_samples;
+ std::vector<std::string> m_samples;
boost::ptr_vector<ProgressBar> m_vumeters;
boost::scoped_ptr<ThemePractice> theme;
};
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index a7987b9..8add471 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -19,7 +19,7 @@ namespace portaudio {
PaError m_code;
char const* m_func;
};
-
+
namespace internal {
void check(PaError code, char const* func) { if (code != paNoError) throw Error(code, func); }
}
@@ -70,7 +70,7 @@ namespace portaudio {
Params& hostApiSpecificStreamInfo(void* val) { params.hostApiSpecificStreamInfo = val; return *this; }
operator PaStreamParameters const*() const { return ¶ms; }
};
-
+
template <typename Functor> int functorCallback(void const* input, void* output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) {
return (*static_cast<Functor*>(userData))(input, output, frameCount, timeInfo, statusFlags);
}
|
|
From: Felix B. <fbe...@us...> - 2010-07-04 21:44:47
|
Module: performous
Branch: master
Commit: c783bf544100b9501830fd34c256ac9e30324b8a
Author: Felix Bertram <fl...@be...>
Date: Sun Jul 4 14:43:37 2010 -0700
Slowdown play
- uses pre-created time-stretched audio files
- minimal changes to code, uses warped time-base
---
game/audio.cc | 44 +++++++++++++++++++++++++++++++++++---------
game/audio.hh | 7 +++++--
game/guitargraph.cc | 4 +++-
game/main.cc | 2 ++
game/screen_sing.cc | 8 ++++++--
game/screen_sing.hh | 1 +
6 files changed, 52 insertions(+), 14 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index ae4acfb..18824d8 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -5,6 +5,7 @@
#include <libda/fft.hpp> // For M_PI
#include <cmath>
#include <iostream>
+#include <boost/filesystem.hpp>
struct SampleStream {
SampleStream(boost::shared_ptr<FFmpeg> const& mpeg): m_mpeg(mpeg) {}
@@ -75,19 +76,39 @@ void Audio::play(Sample const& s, std::string const& volumeSetting) {
m_mixer.add(da::shared_ref(acc));
}
-void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool preview, double fadeTime, double startPos) {
+void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool preview, double fadeTime, double startPos, int speed) {
if (!isOpen()) return;
da::lock_holder l = m_mixer.lock();
fadeout(fadeTime);
boost::shared_ptr<da::chain> ch(new da::chain());
for(std::map<std::string,std::string>::const_iterator it = filenames.begin() ; it != filenames.end() ; ++it ) {
+ std::string f;
try {
- boost::shared_ptr<Stream> s(new Stream(it->second, m_rs.rate()));
+ f = it->second;
+ if (speed != 100) {
+ // instead of real-time time-stretching we use previously created files
+ // best effects have been achieved with SBSMS library
+ // as used by Audacity's Sliding Time Scale/ Pitch Shift plugin
+ std::string f2 = "-" + boost::lexical_cast<std::string>(speed) + ".ogg";
+ f.replace(f.find(".ogg"), 4, f2);
+ // std::cout << "loading time-stretched audio (" << f << ")" << std::endl;
+
+ if (!boost::filesystem::exists(f)) throw std::runtime_error("time-stretched file \"" + f +"\" not found");
+ }
+
+ boost::shared_ptr<Stream> s(new Stream(f, m_rs.rate()));
m_streams[it->first] = s;
ch->add(da::shared_ref(s));
s->seek(startPos);
} catch (std::runtime_error& e) {
- std::cerr << "Error loading " << it->second << " (" << e.what() << ")" << std::endl;
+ if (speed != 100) {
+ // in case time-stretching failed let's retry at normal speed
+ // TODO: we could also auto-create time-stretched files here
+ playMusic(filenames, preview, fadeTime, startPos, 100);
+ return;
+ }
+ // in case we are at normal speed we skip this file and try to continue
+ std::cerr << "Error loading " << f << " (" << e.what() << ")" << std::endl;
continue;
}
}
@@ -96,12 +117,14 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
ch->add(boost::ref(m_volume));
m_mixer.fadein(da::shared_ref(ch), fadeTime, startPos);
if (!preview) pause(false);
+
+ m_speed = speed;
}
-void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
+void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos, int speed) {
std::map<std::string,std::string> tmp;
tmp["unidentified"] = filename;
- playMusic(tmp, preview, fadeTime, startPos);
+ playMusic(tmp, preview, fadeTime, startPos, speed);
}
void Audio::stopMusic() {
@@ -120,12 +143,13 @@ void Audio::fadeout(double fadeTime) {
double Audio::getPosition() const {
da::lock_holder l = m_mixer.lock();
- return m_streams.empty() ? getNaN() : m_streams.begin()->second->pos();
+ // only the audio slows down; the game still uses original time base
+ return m_streams.empty() ? getNaN() : m_streams.begin()->second->pos() * m_speed/100.0;
}
double Audio::getLength() const {
da::lock_holder l = m_mixer.lock();
- return m_streams.empty() ? getNaN() : m_streams.begin()->second->duration();
+ return m_streams.empty() ? getNaN() : m_streams.begin()->second->duration() * m_speed/100.0;
}
bool Audio::isPlaying() const {
@@ -133,14 +157,16 @@ bool Audio::isPlaying() const {
return m_streams.empty() ? false : !m_streams.begin()->second->eof();
}
-void Audio::seek(double offset) {
+void Audio::seek(double offset2) {
+ double offset = offset2 * 100.0/m_speed;
da::lock_holder l = m_mixer.lock();
for(std::map<std::string,boost::shared_ptr<Stream> >::iterator it = m_streams.begin() ; it != m_streams.end() ; ++it)
it->second->seek(clamp(it->second->pos() + offset, 0.0, it->second->duration()));
pause(false);
}
-void Audio::seekPos(double pos) {
+void Audio::seekPos(double pos2) {
+ double pos = pos2 * 100.0/m_speed;
da::lock_holder l = m_mixer.lock();
for(std::map<std::string,boost::shared_ptr<Stream> >::iterator it = m_streams.begin() ; it != m_streams.end() ; ++it)
it->second->seek(pos);
diff --git a/game/audio.hh b/game/audio.hh
index e4f701f..d441cb1 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -94,9 +94,9 @@ class Audio {
* @param fadeTime time to fade
* @param startPos starting position
*/
- void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.5, double startPos = -0.2);
+ void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.5, double startPos = -0.2, int speed = 100);
/// plays a list of songs
- void playMusic(std::map<std::string,std::string> const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = -0.2);
+ void playMusic(std::map<std::string,std::string> const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = -0.2, int speed = 100);
/// plays a sample
void play(Sample const& s, std::string const& volumeSetting);
/// get pause status
@@ -107,6 +107,8 @@ class Audio {
void fadeout(double time = 1.0);
/** Get the length of the currently playing song, in seconds. **/
double getLength() const;
+ /// return current speed
+ int getSpeed() {return m_speed;}
/**
* This methods seek forward in the stream (backwards if
* argument is negative), and continues playing.
@@ -137,5 +139,6 @@ class Audio {
std::string m_volumeSetting;
da::mixer m_mixer;
std::map<std::string,boost::shared_ptr<Stream> > m_streams;
+ int m_speed;
};
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 0be7a41..0fdf6aa 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -185,7 +185,9 @@ bool GuitarGraph::difficulty(Difficulty level) {
/// Core engine
void GuitarGraph::engine() {
double time = m_audio.getPosition();
- time -= config["audio/controller_delay"].f();
+ // need to compensate for speed as well. When playing at half speed,
+ // 1 second from getPosition is actually two seconds in real time
+ time -= config["audio/controller_delay"].f() * m_audio.getSpeed()/100.0;
// Handle key markers
if (!m_drums) {
for (int i = 0; i < m_pads; ++i) {
diff --git a/game/main.cc b/game/main.cc
index 91aed77..03da057 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -145,6 +145,8 @@ void audioSetup(Capture& capture, Audio& audio) {
if (channels != 2) throw std::runtime_error("Only stereo playback is supported, error in pdev=" + *it);
try {
audio.open(devstr, rate, frames);
+ // when we get here, we have successfully opened a device. let's use it!
+ break;
} catch (std::exception const& e) {
std::cerr << "Playback device pdev=" << *it << " failed and will be ignored:\n " << e.what() << std::endl;
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index dd822f3..0b52e85 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -31,6 +31,7 @@ namespace {
void ScreenSing::enter() {
//m_practmode = true; // un-comment this line to play with practice mode. temporary, of course!
+ m_speed = 75; // 75% slow-down; falls back to 100% if time-stretch files are not found. temporary, of course!
ScreenManager* sm = ScreenManager::getSingletonPtr();
sm->flashMessage(_("Loading song..."), 0.0, 1.0, 0.5);
sm->drawFlashMessage(); sm->window().swap(); // Make loading message show
@@ -85,6 +86,7 @@ void ScreenSing::enter() {
theme->timer.dimensions.screenTop(0.5 * m_progress->dimensions.h());
boost::ptr_vector<Analyzer>& analyzers = m_capture.analyzers();
m_layout_singer.reset(new LayoutSinger(m_song->vocals, m_database, theme));
+
// Load instrument and dance tracks
{
int type = 0; // 0 for dance, 1 for guitars, 2 for drums
@@ -108,7 +110,7 @@ void ScreenSing::enter() {
}
// Startup delay for instruments is longer than for singing only
double setup_delay = (m_instruments.empty() && m_dancers.empty() ? -1.0 : -8.0);
- m_audio.playMusic(m_song->music, false, 0.0, setup_delay);
+ m_audio.playMusic(m_song->music, false, 0.0, setup_delay, m_speed);
m_engine.reset(new Engine(m_audio, m_song->vocals, analyzers.begin(), analyzers.end(), m_database));
}
@@ -317,7 +319,9 @@ void ScreenSing::draw() {
// Get the time in the song
double length = m_audio.getLength();
double time = m_audio.getPosition();
- time -= config["audio/video_delay"].f();
+ // need to compensate for speed as well. When playing at half speed,
+ // 1 second from getPosition is actually two seconds in real time
+ time -= config["audio/video_delay"].f() * m_audio.getSpeed()/100.0;
double songPercent = clamp(time / length);
// Rendering starts
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index c743877..16cff8e 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -93,5 +93,6 @@ class ScreenSing: public Screen {
AnimValue m_quitTimer;
bool m_only_singers_alive;
bool m_practmode;
+ int m_speed; // speed in percent, 100 for normal, 50 for half
};
|
|
From: Felix B. <fbe...@us...> - 2010-07-02 17:21:56
|
Module: performous Branch: master Commit: 107a4c07d8a03dffa603a6d38eed6476c83bd70c Author: Felix Bertram <fl...@be...> Date: Fri Jul 2 10:20:13 2010 -0700 Midi I/O does not compile under Fedora 13 libporttime does not exist on Fedora 13 --- cmake/Modules/FindPortMidi.cmake | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/cmake/Modules/FindPortMidi.cmake b/cmake/Modules/FindPortMidi.cmake index f5126d8..38224a0 100644 --- a/cmake/Modules/FindPortMidi.cmake +++ b/cmake/Modules/FindPortMidi.cmake @@ -13,7 +13,7 @@ include(LibFindMacros) find_path(PortMidi_INCLUDE_DIR NAMES portmidi.h) find_library(PortMidi_LIBRARY NAMES portmidi) -find_library(PortTime_LIBRARY NAMES porttime) +find_library(PortTime_LIBRARY NAMES portmidi) set(PortMidi_PROCESS_INCLUDES PortMidi_INCLUDE_DIR) set(PortMidi_PROCESS_LIBS PortMidi_LIBRARY PortTime_LIBRARY) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2010-06-24 00:47:36
|
Module: performous Branch: portaudio Commit: c98951d17e65b78b99834e8852e6f811d6f5822a Author: Lasse Karkkainen <tro...@tr...> Date: Thu Jun 24 03:44:34 2010 +0300 - Config schema for new audio device configuration - Audio code rewritten with multiple device support - Samples now take std::string const& instead of std::string * Must use std::auto_ptr for ptr_map insert (avoid leaks when key copycon throws) --- data/schema.xml | 25 +++------ game/audio.cc | 154 +++++++++++++++++++++++++++++++++--------------------- game/audio.hh | 6 +- 3 files changed, 105 insertions(+), 80 deletions(-) |
|
From: Tapio V. <aa...@us...> - 2010-06-23 18:37:18
|
Module: performous
Branch: master
Commit: 2ea1b45f0368a74a30f8782d318598495823c1ba
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jun 23 21:35:13 2010 +0300
Add a popup at the beginning of a dance stop.
---
game/dancegraph.cc | 16 ++++++++++++++--
game/dancegraph.hh | 1 +
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/game/dancegraph.cc b/game/dancegraph.cc
index cf9c556..5b19a65 100644
--- a/game/dancegraph.cc
+++ b/game/dancegraph.cc
@@ -78,7 +78,8 @@ DanceGraph::DanceGraph(Audio& audio, Song const& song):
m_arrows_cursor(getThemePath("arrows_cursor.svg")),
m_arrows_hold(getThemePath("arrows_hold.svg")),
m_mine(getThemePath("mine.svg")),
- m_flow_direction(1)
+ m_flow_direction(1),
+ m_insideStop()
{
// Initialize some arrays
for(size_t i = 0; i < max_panels; i++) {
@@ -177,11 +178,22 @@ void DanceGraph::difficulty(DanceDifficulty level) {
void DanceGraph::engine() {
double time = m_audio.getPosition();
time -= config["audio/controller_delay"].f();
+ // Handle stops
+ bool outsideStop = true;
for (Song::Stops::const_iterator it = m_song.stops.begin(), end = m_song.stops.end(); it != end; ++it) {
if (it->first >= time) break;
- if (time < it->first + it->second) { time = it->first; break; } // Inside stop
+ if (time < it->first + it->second) { // Inside stop
+ time = it->first;
+ if (!m_insideStop) {
+ m_popups.push_back(Popup(_("STOP!"), glutil::Color(1.0f, 0.8f, 0.0), 2.0, m_popupText.get()));
+ m_insideStop = true;
+ }
+ outsideStop = false;
+ break;
+ }
time -= it->second;
}
+ if (outsideStop && m_insideStop) m_insideStop = false;
if (joining(time)) m_dead = 0; // Disable dead counting while joining
bool difficulty_changed = false;
// Handle all events
diff --git a/game/dancegraph.hh b/game/dancegraph.hh
index cfdd705..0eff7b7 100644
--- a/game/dancegraph.hh
+++ b/game/dancegraph.hh
@@ -80,5 +80,6 @@ class DanceGraph: public InstrumentGraph {
// Misc
int m_arrow_map[max_panels]; /// game mode dependant mapping of arrows' ordering at cursor
int m_flow_direction;
+ bool m_insideStop;
};
|
|
From: Tapio V. <aa...@us...> - 2010-06-23 18:20:56
|
Module: performous
Branch: joinmenu
Commit: 464fd8db834388590beefac936fc1282de6890f1
Author: Tapio Vierros <tap...@gm...>
Date: Wed Jun 23 21:17:06 2010 +0300
Theming support for instrument menu.
* Uses SVGs from main menu for place holders.
- Not very well suited.
* Background images are disabled.
- Waiting for proper pics to tune them with.
---
game/instrumentgraph.cc | 24 +++++++++++++++---------
game/menu.hh | 5 ++++-
game/theme.cc | 4 +---
game/theme.hh | 2 +-
4 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/game/instrumentgraph.cc b/game/instrumentgraph.cc
index 1c31753..470af9c 100644
--- a/game/instrumentgraph.cc
+++ b/game/instrumentgraph.cc
@@ -52,20 +52,26 @@ void InstrumentGraph::toggleMenu(int dontforce) {
void InstrumentGraph::drawMenu(double offsetX) {
if (m_menu.options.empty()) return;
- float step = 0.05;
+ float step = 0.075;
float y = -0.5 * m_menu.options.size() * step;
- m_text.dimensions.screenCenter(0).middle(0);
+ ThemeInstrumentMenu& th = *m_menu.theme;
for (InstrumentMenuOptions::iterator it = m_menu.options.begin(); it != m_menu.options.end(); ++it) {
- // TODO: Use theme
- m_text.dimensions.center(y).middle(-0.09 + offsetX);
- std::string value = it->value;
- if (m_menu.current == it) value = "> " + value + " <";
- m_text.draw(value);
+ if (m_menu.current == it) {
+ //th.back_h.dimensions.middle(0.05 + offsetX).center(y);
+ //th.back_h.draw();
+ th.option_selected.dimensions.middle(-0.1 + offsetX).center(y);
+ th.option_selected.draw(it->value);
+ } else {
+ th.option.dimensions.middle(-0.1 + offsetX).center(y);
+ th.option.draw(it->value);
+ }
y += step;
}
if (m_menu.current->comment != "") {
- m_text.dimensions.center(y+3*step).middle(-0.09 + offsetX);
- m_text.draw(m_menu.current->comment);
+ //th.comment_bg.dimensions.middle().screenBottom(-0.2);
+ //th.comment_bg.draw();
+ th.comment.dimensions.middle(-0.1 + offsetX).screenBottom(-0.2);
+ th.comment.draw(m_menu.current->comment);
}
}
diff --git a/game/menu.hh b/game/menu.hh
index 7afb371..7ebe636 100755
--- a/game/menu.hh
+++ b/game/menu.hh
@@ -2,7 +2,9 @@
#include "opengl_text.hh"
#include "surface.hh"
+#include "theme.hh"
#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
#include <string>
#include <vector>
@@ -50,7 +52,7 @@ typedef std::vector<InstrumentMenuOption> InstrumentMenuOptions;
/// Menu for selecting difficulty etc.
struct InstrumentMenu {
/// constructor
- InstrumentMenu(InstrumentGraph& ig): owner(ig), current(options.end()) {}
+ InstrumentMenu(InstrumentGraph& ig): owner(ig), current(options.end()) { theme.reset(new ThemeInstrumentMenu()); }
/// add a menu option
void add(InstrumentMenuOption opt);
/// move the selection
@@ -65,4 +67,5 @@ struct InstrumentMenu {
InstrumentGraph& owner;
InstrumentMenuOptions options;
InstrumentMenuOptions::iterator current;
+ boost::scoped_ptr<ThemeInstrumentMenu> theme;
};
diff --git a/game/theme.cc b/game/theme.cc
index e583b1d..24add72 100755
--- a/game/theme.cc
+++ b/game/theme.cc
@@ -63,12 +63,10 @@ ThemeIntro::ThemeIntro():
ThemeInstrumentMenu::ThemeInstrumentMenu():
Theme(getThemePath("warning.svg")),
back_h(getThemePath("menu_back_highlight.svg")),
+ option(getThemePath("menu_option.svg"), config["graphic/text_lod"].f()),
option_selected(getThemePath("menu_option_selected.svg"), config["graphic/text_lod"].f()),
comment(getThemePath("menu_comment.svg"), config["graphic/text_lod"].f()),
comment_bg(getThemePath("menu_comment_bg.svg"))
{
back_h.dimensions.fixedHeight(0.08f);
- option.push_back(new SvgTxtTheme(getThemePath("menu_option.svg"), config["graphic/text_lod"].f()));
- option.push_back(new SvgTxtTheme(getThemePath("menu_option.svg"), config["graphic/text_lod"].f()));
- option.push_back(new SvgTxtTheme(getThemePath("menu_option.svg"), config["graphic/text_lod"].f()));
}
diff --git a/game/theme.hh b/game/theme.hh
index 0e3e042..c1c9ffa 100755
--- a/game/theme.hh
+++ b/game/theme.hh
@@ -97,7 +97,7 @@ struct ThemeInstrumentMenu: Theme {
/// back highlight for selected option
Surface back_h;
/// menu option text
- boost::ptr_vector<SvgTxtTheme> option;
+ SvgTxtTheme option;
/// menu selected option text
SvgTxtTheme option_selected;
/// menu comment text
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2010-06-23 05:28:23
|
Module: performous
Branch: portaudio
Commit: 2661a16adb2a245da582970940c8f30387b56783
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jun 23 08:27:59 2010 +0300
Cleanup
---
game/audio.cc | 34 ++++++++++++++++++++--------------
game/audio.hh | 5 +++--
2 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 4cd5ae4..899615a 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -13,8 +13,8 @@
class Music {
struct Track {
FFmpeg mpeg;
- float volume;
- Track(std::string const& filename, unsigned int sr): mpeg(false, true, filename, sr), volume(1.0f) {}
+ float fadeLevel;
+ Track(std::string const& filename, unsigned int sr): mpeg(false, true, filename, sr), fadeLevel(1.0f) {}
};
typedef boost::ptr_map<std::string, Track> Tracks;
Tracks tracks; ///< Audio decoders
@@ -35,7 +35,7 @@ public:
std::vector<float> mixbuf(end - begin);
for (Tracks::iterator it = tracks.begin(), itend = tracks.end(); it != itend; ++it) {
Track& t = *it->second;
- if (t.mpeg.audioQueue(&*mixbuf.begin(), &*mixbuf.end(), m_pos, t.volume)) eof = false;
+ if (t.mpeg.audioQueue(&*mixbuf.begin(), &*mixbuf.end(), m_pos, t.fadeLevel)) eof = false;
}
m_pos += end - begin;
for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
@@ -66,10 +66,10 @@ public:
}
return ready;
}
- void trackLevel(std::string const& id, double level) {
- Tracks::iterator it = tracks.find(id);
+ void trackFade(std::string const& name, double fadeLevel) {
+ Tracks::iterator it = tracks.find(name);
if (it == tracks.end()) return;
- it->second->volume = level;
+ it->second->fadeLevel = fadeLevel;
}
};
@@ -103,7 +103,11 @@ struct SampleNew {
};
-typedef std::pair<std::string, double> Command; ///< <stream ID, volume level>
+struct Command {
+ enum { TRACK_FADE } type;
+ std::string track;
+ double fadeLevel;
+};
struct Audio::Impl {
boost::mutex mutex;
@@ -133,9 +137,12 @@ struct Audio::Impl {
}
// Process commands
for (size_t i = 0; i < commands.size(); ++i) {
- std::string id = commands[i].first;
- double level = commands[i].second;
- if (!playing.empty()) playing[0].trackLevel(id, level);
+ Command const& cmd = commands[i];
+ switch (cmd.type) {
+ case Command::TRACK_FADE:
+ if (!playing.empty()) playing[0].trackFade(cmd.track, cmd.fadeLevel);
+ break;
+ }
}
commands.clear();
}
@@ -184,7 +191,6 @@ bool Audio::isOpen() const {
}
void Audio::loadSample(std::string streamId, std::string filename) {
- std::cout << ">>> Loading sample \"" << streamId << "\"" << std::endl;
{
boost::mutex::scoped_lock l(self->mutex);
self->samples.insert(streamId, new SampleNew(filename, getSR()));
@@ -200,7 +206,6 @@ void Audio::playSample(std::string streamId) {
}
void Audio::unloadSample(std::string streamId) {
- std::cout << ">>> Unloading sample \"" << streamId << "\"" << std::endl;
{
boost::mutex::scoped_lock l(self->mutex);
self->samples.erase(streamId);
@@ -270,9 +275,10 @@ void Audio::pause(bool state) {
bool Audio::isPaused() const { return self->paused; }
-void Audio::streamFade(std::string stream_id, double level) {
+void Audio::streamFade(std::string track, double fadeLevel) {
boost::mutex::scoped_lock l(self->mutex);
- self->commands.push_back(Command(stream_id, level));
+ Command cmd = { Command::TRACK_FADE, track, fadeLevel };
+ self->commands.push_back(cmd);
}
boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
diff --git a/game/audio.hh b/game/audio.hh
index cab5e4f..53ce5b2 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -54,8 +54,9 @@ public:
void togglePause() { pause(!isPaused()); }
void pause(bool state = true);
bool isPaused() const;
- void toggleSynth(Notes const& notes) { /*m_notes = (m_notes ? NULL : ¬es); */} ///< toggles synth playback
- void streamFade(std::string stream_id, double level);
+ void toggleSynth(Notes const&) { /*m_notes = (m_notes ? NULL : ¬es); */} ///< toggles synth playback
+ /// Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0.
+ void streamFade(std::string track, double volume);
double getSR() const { return 48000.0; }
};
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2010-06-23 05:28:21
|
Module: performous
Branch: portaudio
Commit: 90ec6dd54629b5a447ee2154b962cb25d3f303d9
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jun 23 08:11:40 2010 +0300
Implement track fading (the current commands structure is a simple hack which is supposed to be improved to support more things in the future).
---
game/audio.cc | 22 ++++++++++++++++++++--
1 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 7c1779b..4cd5ae4 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -41,8 +41,8 @@ public:
for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
if (i % 2 == 0) {
fadeLevel += fadeRate;
- if (fadeLevel <= 0.0f) return false;
- if (fadeLevel > 1.0f) { fadeLevel = 1.0f; fadeRate = 0.0f; }
+ if (fadeLevel <= 0.0) return false;
+ if (fadeLevel > 1.0) { fadeLevel = 1.0; fadeRate = 0.0; }
}
begin[i] += mixbuf[i] * fadeLevel;
}
@@ -66,6 +66,11 @@ public:
}
return ready;
}
+ void trackLevel(std::string const& id, double level) {
+ Tracks::iterator it = tracks.find(id);
+ if (it == tracks.end()) return;
+ it->second->volume = level;
+ }
};
// rename to Sample once totally implemented
@@ -98,12 +103,15 @@ struct SampleNew {
};
+typedef std::pair<std::string, double> Command; ///< <stream ID, volume level>
+
struct Audio::Impl {
boost::mutex mutex;
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
boost::ptr_map<std::string, SampleNew> samples;
boost::ptr_vector<Analyzer> analyzers;
+ std::vector<Command> commands;
portaudio::Init init;
boost::ptr_vector<portaudio::Stream> streams;
volatile bool paused;
@@ -123,6 +131,13 @@ struct Audio::Impl {
if (!playing.empty()) playing[0].fadeRate = -preloading->fadeRate; // Fade out the old music
playing.insert(playing.begin(), preloading);
}
+ // Process commands
+ for (size_t i = 0; i < commands.size(); ++i) {
+ std::string id = commands[i].first;
+ double level = commands[i].second;
+ if (!playing.empty()) playing[0].trackLevel(id, level);
+ }
+ commands.clear();
}
void callbackInput(float const* begin, float const* end) {
analyzers[0].input(begin, end); // TODO: non-pointer sample iterators and support more analyzers
@@ -199,6 +214,7 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
Music& m = *self->preloading.get();
m.seek(startPos);
m.fadeRate = 1.0 / getSR() / fadeTime;
+ self->commands.clear(); // Remove old unprocessed commands (they should not apply to the new music)
}
void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
@@ -255,6 +271,8 @@ void Audio::pause(bool state) {
bool Audio::isPaused() const { return self->paused; }
void Audio::streamFade(std::string stream_id, double level) {
+ boost::mutex::scoped_lock l(self->mutex);
+ self->commands.push_back(Command(stream_id, level));
}
boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2010-06-23 04:33:50
|
Module: performous
Branch: portaudio
Commit: 62e1916e4be836cc53f4cf563874f618f34adcac
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jun 23 07:33:33 2010 +0300
Implement capture (analyzer) for one channel. Improve code comments in audio.cc.
---
game/audio.cc | 31 +++++++++++++++++++++----------
game/audio.hh | 2 +-
game/engine.hh | 1 +
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 3a6c9e8..7c1779b 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -103,12 +103,15 @@ struct Audio::Impl {
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
boost::ptr_map<std::string, SampleNew> samples;
+ boost::ptr_vector<Analyzer> analyzers;
portaudio::Init init;
boost::ptr_vector<portaudio::Stream> streams;
volatile bool paused;
Impl(): paused(false) {
std::string dev;
- streams.push_back(new portaudio::Stream(*this, portaudio::Params().channelCount(2).device(dev, true), portaudio::Params().channelCount(2).device(dev, false), 48000));
+ streams.push_back(new portaudio::Stream(*this, portaudio::Params().channelCount(1).device(dev, true), portaudio::Params().channelCount(2).device(dev, false), 48000));
+ // One analyzer for mono input (TODO: fix callbackInput to allow more)
+ analyzers.push_back(new Analyzer(48000.0));
PaError err = Pa_StartStream(streams[0]);
if( err != paNoError ) throw std::runtime_error("Cannot start PortAudio audio stream " + dev + ": " + Pa_GetErrorText(err));
}
@@ -121,17 +124,24 @@ struct Audio::Impl {
playing.insert(playing.begin(), preloading);
}
}
- void callbackInput(float const* begin, float const* end) {}
+ void callbackInput(float const* begin, float const* end) {
+ analyzers[0].input(begin, end); // TODO: non-pointer sample iterators and support more analyzers
+ }
void callbackOutput(float* begin, float* end) {
std::fill(begin, end, 0.0f);
if (paused) return;
+ // Mix in from the streams currently playing
for (size_t i = 0; i < playing.size();) {
- bool keep = playing[i](begin, end);
- // Disposing hack
- boost::mutex::scoped_try_lock l(mutex);
- if (!l.owns_lock()) keep = true; // Cannot dispose without lock
- if (keep) ++i; else disposing.transfer(disposing.end(), playing.begin() + i, playing);
+ bool keep = playing[i](begin, end); // Do the actual mixing
+ boost::mutex::scoped_try_lock l(mutex, boost::defer_lock);
+ if (!keep && l.try_lock()) {
+ // Dispose streams no longer needed by moving them to another container (that will be cleared by another thread).
+ disposing.transfer(disposing.end(), playing.begin() + i, playing);
+ continue;
+ }
+ ++i;
}
+ // Mix in the samples currently playing
for(boost::ptr_map<std::string, SampleNew>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
boost::mutex::scoped_try_lock l(mutex);
(*it->second)(begin, end);
@@ -140,10 +150,9 @@ struct Audio::Impl {
int operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
float const* in = static_cast<float const*>(input);
float* out = static_cast<float*>(output);
- size_t samples = 2 * frames;
- callbackInput(in, in + samples);
+ callbackInput(in, in + 1 * frames); // TODO: no hardcoded channel count
callbackUpdate();
- callbackOutput(out, out + samples);
+ callbackOutput(out, out + 2 * frames);
return paContinue;
} catch (std::exception& e) {
std::cerr << "Exception in audio callback: " << e.what() << std::endl;
@@ -248,3 +257,5 @@ bool Audio::isPaused() const { return self->paused; }
void Audio::streamFade(std::string stream_id, double level) {
}
+boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
+
diff --git a/game/audio.hh b/game/audio.hh
index 4f620ee..cab5e4f 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -18,7 +18,7 @@ class Audio {
public:
Audio();
~Audio();
- boost::ptr_vector<Analyzer>& analyzers() { static boost::ptr_vector<Analyzer> ana; return ana; }
+ boost::ptr_vector<Analyzer>& analyzers();
bool isOpen() const;
/** Play a song beginning at startPos (defaults to 0)
* @param filename the track filename
diff --git a/game/engine.hh b/game/engine.hh
index f1c7882..c2dad6d 100644
--- a/game/engine.hh
+++ b/game/engine.hh
@@ -65,6 +65,7 @@ class Engine {
std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::prepare, _1));
double t = m_audio.getPosition() - config["audio/round-trip"].f();
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_vocals.notes.begin(); it != m_vocals.notes.end(); ++it) it->power = 0.0f;
std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::update, _1));
|
|
From: Tapio V. <aa...@us...> - 2010-06-22 20:05:31
|
Module: performous
Branch: master
Commit: b85c1ebb52719be4a71a2fb127a3ce7460161f63
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jun 22 23:03:56 2010 +0300
Add starpower button to Hama mapping.
---
game/joystick.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/joystick.cc b/game/joystick.cc
index e2a71a3..8c1cf66 100644
--- a/game/joystick.cc
+++ b/game/joystick.cc
@@ -121,7 +121,7 @@ int input::buttonFromSDL(input::detail::Type _type, unsigned int _sdl_button) {
{ 0, 1, 3, 2, 4,-1, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1 }, // Guitar Hero X-plorer guitar
{ 3, 0, 1, 2, 4, 5, -1, -1, 8, 9, -1, -1, -1, -1, -1, -1 }, // Rock Band guitar PS3
{ 0, 1, 3, 2, 4,-1, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1 }, // Rock Band guitar XBOX360
- { 2, 1, 3, 4,-1, 0, -1, -1, 8, 9, -1, -1, -1, -1, -1, -1 }, // Hama Wireless Guitar Controller for PS2 with converter
+ { 2, 1, 3, 4, 5, 0, -1, -1, 8, 9, -1, -1, -1, -1, -1, -1 }, // Hama Wireless Guitar Controller for PS2 with converter
//K R Y B G O // for drums
{ 3, 4, 1, 2, 0, 4, -1, -1, 8, 9, -1, -1, -1, -1, -1, -1 }, // Guitar Hero drums
{ 3, 4, 1, 2, 0,-1, -1, -1, 8, 9, -1, -1, -1, -1, -1, -1 }, // Rock Band drums PS3
|
|
From: Tapio V. <aa...@us...> - 2010-06-22 18:52:42
|
Module: performous Branch: joinmenu Commit: 0a988dc055e2e306be14ea5fd031e067af5d7eed Author: Tapio Vierros <tap...@gm...> Date: Tue Jun 22 21:50:59 2010 +0300 Work on instrument menu. * Pause menu. - Game pauses if any menus are open. - Currently only resume and quit actions. * Esc-key invokes global pause (menus for all). * Game doesn't start if players aren't ready. * InstrumentMenuOption doesn't have to have getter func. * Added i18n stuff. * Still looks butt-ugly. * Much cleaning required, with heavy duty chemicals. --- game/dancegraph.cc | 24 +++++++++--------- game/guitargraph.cc | 34 ++++++++++++++++----------- game/instrumentgraph.cc | 54 +++++++++++++++++++++++++++++++++++++++++- game/instrumentgraph.hh | 32 ++++++++++--------------- game/joystick.cc | 5 ++++ game/menu.cc | 32 ++++++++++++++++-------- game/menu.hh | 13 +++++++--- game/screen_sing.cc | 59 ++++++++++++++++++++++++++++++++-------------- 8 files changed, 173 insertions(+), 80 deletions(-) |