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...> - 2011-01-24 16:36:31
|
Module: editor
Branch: master
Commit: 96698a4ee9e51cafc733243da941b1dad7f19149
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 18:33:37 2011 +0200
Some SS XML writer fixes.
XML exported notes can now be parsed, although the imports are b0rked.
---
songwriter-xml.cc | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/songwriter-xml.cc b/songwriter-xml.cc
index 557ceee..e114f8f 100644
--- a/songwriter-xml.cc
+++ b/songwriter-xml.cc
@@ -30,11 +30,12 @@ void SingStarXMLWriter::writeXML() {
QDomElement trackElem = doc.createElement("TRACK");
trackElem.setAttribute("Name", "Player1");
trackElem.setAttribute("Artist", QString::fromStdString(s.artist));
+ root.appendChild(trackElem);
int sentencenum = 1;
QDomElement sentenceElem = doc.createElement("SENTENCE"); // FIXME: Should there be Singer and Part attributes?
QDomComment sentenceComment = doc.createComment(QString("Track %1, Sentence %2").arg(tracknum).arg(sentencenum));
- trackElem.appendChild(sentenceComment);
+ sentenceElem.appendChild(sentenceComment);
// Iterate all notes
Notes const& notes = s.getVocalTrack().notes;
@@ -43,7 +44,7 @@ void SingStarXMLWriter::writeXML() {
// SLEEP notes indicate sentence end
if (n.type == Note::SLEEP) {
- trackElem.appendChild(sentenceElem);
+ root.appendChild(sentenceElem);
++sentencenum;
sentenceElem = doc.createElement("SENTENCE");
sentenceComment = doc.createComment(QString("Track %1, Sentence %2").arg(tracknum).arg(sentencenum));
@@ -77,7 +78,7 @@ void SingStarXMLWriter::writeXML() {
// TODO: Needs a last dummy sentence
- root.appendChild(trackElem);
+ root.appendChild(sentenceElem);
// Get the xml data
QString xml = doc.toString(4);
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 16:36:29
|
Module: editor
Branch: master
Commit: 8f056c2890fc3702aa886ff66b2a738be1dc1b4a
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 18:30:05 2011 +0200
SingStar XML song parser.
Seems to be mostly working, but not perfect.
---
songparser-xml.cc | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/songparser-xml.cc b/songparser-xml.cc
index 3109d9f..919b075 100644
--- a/songparser-xml.cc
+++ b/songparser-xml.cc
@@ -1,6 +1,8 @@
#include "songparser.hh"
#include <QtXml/QDomDocument>
-#include <QTextStream>
+#include <QFile>
+#include <QtGlobal>
+#include <iostream>
@@ -11,17 +13,113 @@ int sleepts = -1;
/// 'Magick' to check if this file looks like correct format
bool SongParser::xmlCheck(std::vector<char> const& data)
{
- return data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' && data[4] == 'l';
+ return (data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' && data[4] == 'l')
+ || (data[0] == '<' && data[1] == 'M' && data[2] == 'E' && data[3] == 'L');
}
void SongParser::xmlParseHeader()
{
+ // Build DOM tree from the xml file
+ QDomDocument doc("MELODY");
+ QFile file(QString::fromStdString(m_song.path) + QString::fromStdString(m_song.filename));
+ if (!file.open(QIODevice::ReadOnly))
+ throw std::runtime_error(QT_TR_NOOP("Couldn't open file"));
+ if (!doc.setContent(&file)) {
+ throw std::runtime_error(QT_TR_NOOP("XML parse error")); }
+ file.close();
+ VocalTrack vocal(TrackName::LEAD_VOCAL);
+ Notes& notes = vocal.notes;
+
+ // Parse meta
+ QDomElement root = doc.documentElement();
+ m_bpm = root.attribute("Tempo").toInt();
+ if (m_bpm == 0)
+ throw std::runtime_error(QT_TR_NOOP("Invalid tempo"));
+ if (root.attribute("Resolution") == QString("Demisemiquaver"))
+ m_bpm *= 2;
+ addBPM(0, m_bpm);
+ m_song.genre = root.attribute("Genre").toStdString();
+ m_song.year = root.attribute("Year").toStdString();
+
+ bool track_found = false; // FIXME: HACK: We only parse the first track
+
+ // Loop through the child elements
+ QDomElement elem = root.firstChildElement();
+ while (!elem.isNull()) {
+
+ if (elem.tagName() == "TRACK") {
+ // Track found
+ if (track_found) break; // FIXME: HACK: We only parse the first track
+ track_found = true;
+ m_song.artist = elem.attribute("Artist").toStdString();
+
+ } else if (elem.tagName() == "SENTENCE") {
+ // Sentence found
+ // Loop through the notes in the sentence
+ QDomElement noteElem = elem.firstChildElement();
+ while (!noteElem.isNull()) {
+
+ // We are only interested in NOTE elements
+ if (noteElem.tagName() == "NOTE") {
+ // Note found
+ int length = noteElem.attribute("Duration").toInt();
+ unsigned int ts = m_prevts;
+
+ // See if it is an actual note and not sleep
+ if (noteElem.attribute("MidiNote") != "0" || !noteElem.attribute("Lyric").isEmpty()) {
+ // TODO: Prettify lyric? (as ss_extract)
+ Note n(noteElem.attribute("Lyric").toStdString());
+ if (noteElem.attribute("Bonus") == QString("Yes"))
+ n.type = Note::GOLDEN;
+ else if (noteElem.attribute("FreeStyle") == QString("Yes"))
+ n.type = Note::FREESTYLE;
+ else
+ n.type = Note::NORMAL;
+
+ n.note = noteElem.attribute("MidiNote").toInt();
+ n.notePrev = n.note; // No slide notes
+ n.begin = tsTime(ts);
+ n.end = tsTime(ts + length);
+
+ // Track note meta
+ vocal.noteMin = std::min(vocal.noteMin, n.note);
+ vocal.noteMax = std::max(vocal.noteMax, n.note);
+
+ // Save note
+ notes.push_back(n);
+ }
+
+ // Update time
+ m_prevts += length;
+ m_prevtime = tsTime(ts + length);
+ }
+ noteElem = noteElem.nextSiblingElement();
+ }
+
+ // Now add sentence end indicators
+ if (!notes.empty()) notes.back().lineBreak = true;
+ Note n;
+ n.type = Note::SLEEP;
+ n.note = 0;
+ n.begin = m_prevtime;
+ n.end = n.begin;
+ notes.push_back(n);
+ }
+ elem = elem.nextSiblingElement();
+ }
+
+ if (!notes.empty()) {
+ vocal.beginTime = notes.front().begin;
+ vocal.endTime = notes.back().end;
+ // Insert notes
+ m_song.insertVocalTrack(TrackName::LEAD_VOCAL, vocal);
+ } else throw std::runtime_error(QT_TR_NOOP("Couldn't find any notes"));
}
void SongParser::xmlParse()
{
-
+ // No op: everything is done in ParseHeader
}
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 16:36:26
|
Module: editor
Branch: master
Commit: 0624dcf3699137e095819046da88a86370a0335f
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 18:28:56 2011 +0200
Parse year from TXT.
---
songparser-txt.cc | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/songparser-txt.cc b/songparser-txt.cc
index 29b7ea4..86d894c 100644
--- a/songparser-txt.cc
+++ b/songparser-txt.cc
@@ -64,6 +64,7 @@ bool SongParser::txtParseField(std::string const& line) {
else if (key == "GAP") { assign(m_gap, value); m_gap *= 1e-3; }
else if (key == "BPM") assign(m_bpm, value);
else if (key == "LANGUAGE") m_song.language= value.substr(value.find_first_not_of(" "));
+ else if (key == "YEAR") m_song.year = value.substr(value.find_first_not_of(" "));
return true;
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 14:19:54
|
Module: editor
Branch: master
Commit: 231213a306c8587d5de3e00a4600c8ef56a0f081
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 15:19:43 2011 +0100
Revert accidentally committed debug code
---
pitchvis.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/pitchvis.cc b/pitchvis.cc
index 9b45539..d3b1678 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -40,7 +40,7 @@ void PitchVis::run()
curX = 0;
for (std::vector<float> data(step*2); mpeg.audioQueue(&*data.begin(), &*data.end(), curX * step * 2); ++curX) {
// Mix stereo into mono
- for (unsigned i = 0; i < step; ++i) data[i] = data[2*i]; //0.5 * (data[2*i] + data[2*i + 1]);
+ for (unsigned i = 0; i < step; ++i) data[i] = 0.5 * (data[2*i] + data[2*i + 1]);
// Process
analyzer.input(&data[0], &data[step]);
analyzer.process();
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 14:17:01
|
Module: editor
Branch: master
Commit: 40c1ba440652a3b3b5e137f6cc1375f9d3c087b7
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 15:16:30 2011 +0100
Various small changes and fixes
---
pitch.cc | 24 ++++++++++--------------
pitch.hh | 23 +++++++++++++++++------
pitchvis.cc | 13 ++++++++-----
pitchvis.hh | 10 +++++-----
4 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/pitch.cc b/pitch.cc
index c0c0bb7..4b81537 100644
--- a/pitch.cc
+++ b/pitch.cc
@@ -61,19 +61,15 @@ namespace {
for (std::size_t n = 1; n < Tone::MAXHARM; ++n) if (matchFreq(n*ff, hf)) return true;
return false;
}
- struct Combo {
- double freq;
- double level;
- Combo(): freq(), level() {}
- void combine(Peak const& p) {
- freq += p.level * p.freq; // Multiplication for weighted average
- level += p.level;
- }
- bool match(double freqOther) const { return matchFreq(freq, freqOther); }
- };
- bool operator<(Combo const& a, Combo const& b) { return a.level < b.level; }
}
+void Combo::combine(Peak const& p) {
+ freq += p.level * p.freq; // Multiplication for weighted average
+ level += p.level;
+}
+
+bool Combo::match(double freqOther) const { return matchFreq(freq, freqOther); }
+
void Analyzer::calcTones() {
// Precalculated constants
const double freqPerBin = m_rate / FFT_N;
@@ -116,9 +112,9 @@ void Analyzer::calcTones() {
// Convert sum frequencies into averages
for (Combos::iterator it = combos.begin(), end = combos.end(); it != end; ++it) it->freq /= it->level;
// Strongest first
- std::sort(combos.rbegin(), combos.rend());
+ std::sort(combos.rbegin(), combos.rend(), Combo::cmpByLevel);
// Keep only a reasonable amount of strongest frequencies.
- if (combos.size() > 10) combos.resize(10);
+ //if (combos.size() > 10) combos.resize(10);
// Try to combine combos into tones (collections of harmonics)
Tones tones;
for (Combos::const_iterator it = combos.begin(), end = combos.end(); it != end; ++it) {
@@ -142,7 +138,7 @@ void Analyzer::calcTones() {
double l = harm->level;
t.harmonics[n - 1] += l;
t.level += l;
- t.freq += l * harm->freq / n; // The sum of all harmonics' fundies (weighted by m)
+ t.freq += l * harm->freq / n; // The sum of all harmonics' fundies (weighted by l)
}
if (miss) ++misses;
}
diff --git a/pitch.hh b/pitch.hh
index 2105c35..d75116e 100644
--- a/pitch.hh
+++ b/pitch.hh
@@ -23,6 +23,13 @@ struct Tone {
Tone* next;
};
+static inline bool operator==(Tone const& lhs, Tone const& rhs) { return lhs == rhs.freq; }
+static inline bool operator!=(Tone const& lhs, Tone const& rhs) { return !(lhs == rhs); }
+static inline bool operator<=(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq || lhs == rhs; }
+static inline bool operator>=(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq || lhs == rhs; }
+static inline bool operator<(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq && lhs != rhs; }
+static inline bool operator>(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq && lhs != rhs; }
+
struct Moment {
typedef std::list<Tone> Tones;
Tones m_tones;
@@ -39,12 +46,16 @@ struct Peak {
Peak(): freqFFT(), freq(), level() {}
};
-static inline bool operator==(Tone const& lhs, Tone const& rhs) { return lhs == rhs.freq; }
-static inline bool operator!=(Tone const& lhs, Tone const& rhs) { return !(lhs == rhs); }
-static inline bool operator<=(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq || lhs == rhs; }
-static inline bool operator>=(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq || lhs == rhs; }
-static inline bool operator<(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq && lhs != rhs; }
-static inline bool operator>(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq && lhs != rhs; }
+/// A combo combines multiple FFT peaks that all display the same frequency into one
+struct Combo {
+ double freq;
+ double level;
+ Combo(): freq(), level() {}
+ void combine(Peak const& p);
+ bool match(double freqOther) const;
+ static bool cmpByLevel(Combo const& a, Combo const& b) { return a.level < b.level; }
+};
+
static const std::size_t BUF_N = 100000; // Ringbuffer size in samples, major b0rkage will happen if this is too small; it won't cause latency, only wasted RAM
diff --git a/pitchvis.cc b/pitchvis.cc
index 20aea67..9b45539 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -40,7 +40,7 @@ void PitchVis::run()
curX = 0;
for (std::vector<float> data(step*2); mpeg.audioQueue(&*data.begin(), &*data.end(), curX * step * 2); ++curX) {
// Mix stereo into mono
- for (unsigned i = 0; i < step; ++i) data[i] = 0.5 * (data[2*i] + data[2*i + 1]);
+ for (unsigned i = 0; i < step; ++i) data[i] = data[2*i]; //0.5 * (data[2*i] + data[2*i + 1]);
// Process
analyzer.input(&data[0], &data[step]);
analyzer.process();
@@ -64,16 +64,19 @@ void PitchVis::run()
Moment::Tones const& tones = it->m_tones;
for (Moment::Tones::const_iterator it2 = tones.begin(), it2end = tones.end(); it2 != it2end; ++it2) {
if (it2->prev) continue; // The tone doesn't begin at this moment, skip
+ // Copy the linked list into vector for easier access and calculate max level
std::vector<Tone const*> tones;
- for (Tone const* n = &*it2; n; n = n->next) tones.push_back(n);
- if (tones.size() < 5) continue; // Too short tone, ignored
+ double lmax = 0.0;
+ for (Tone const* n = &*it2; n; n = n->next) { tones.push_back(n); lmax = std::max(lmax, n->level); }
+ if (tones.size() < 5) continue; // Too short or weak tone, ignored
+ std::cout << tones.size() << ", " << lmax << std::endl;
// Render
for (unsigned i = 0; i < tones.size(); ++i) {
unsigned x = curX + i;
if (x >= width()) throw std::logic_error("Tone past the end of moments");
- float value = 0.003 * (level2dB(tones[i]->level) + 80.0);
+ float value = 0.006 * (level2dB(tones[i]->level) + 60.0);
if (value <= 0.0) continue;
- unsigned int pix = Pixel(0.0f, value, 0.0f).rgba();
+ unsigned int pix = Pixel(0.0f, 1.0f, 0.0f, value).rgba();
unsigned y = freq2px(tones[i]->freq);
for (int j = std::max<int>(0, int(y) - 2), jend = std::min<int>(height, int(y) + 3); j < jend; ++j) rgba[j * width() + x] = pix;
}
diff --git a/pitchvis.hh b/pitchvis.hh
index 1e7b557..cef0ad5 100644
--- a/pitchvis.hh
+++ b/pitchvis.hh
@@ -14,7 +14,7 @@ struct Pixel {
Pixel(float r, float g, float b, float a = 1.0f): r(r), g(g), b(b), a(a) {}
Pixel(): r(), g(), b(), a(1.0f) {}
static unsigned char conv(float c, float a) {
- return static_cast<unsigned char>(255.0 * a * std::sqrt(c)); // sqrt(c) is gamma correction
+ return static_cast<unsigned char>(0.5 + 255.0 * clamp(a * std::sqrt(c))); // sqrt(c) is gamma correction
}
unsigned rgba() const {
unsigned char red = conv(r, a);
@@ -25,10 +25,10 @@ struct Pixel {
}
float& operator[](unsigned idx) { return (&r)[idx]; }
Pixel& operator+=(Pixel const& pix) {
- r = clamp(r + pix.r);
- g = clamp(g + pix.g);
- b = clamp(b + pix.b);
- a = clamp(a + pix.a);
+ r = r + pix.r;
+ g = g + pix.g;
+ b = b + pix.b;
+ a = a + pix.a;
return *this;
}
};
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 11:33:45
|
Module: editor
Branch: master
Commit: 447a4024720900e7b9bc3f55025920335a68eecf
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 13:32:28 2011 +0200
File dialog for music file import defaults to user's music-folder.
---
editorapp.cc | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/editorapp.cc b/editorapp.cc
index 916d627..0489304 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -1,6 +1,7 @@
#include <QProgressBar>
#include <QMessageBox>
#include <QFileDialog>
+#include <QDesktopServices>
#include <QClipboard>
#include <QMimeData>
#include <QWhatsThis>
@@ -376,8 +377,8 @@ void EditorApp::on_actionRedo_triggered()
void EditorApp::on_actionMusicFile_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
- "",
- tr("Music files (*.mp3 *.ogg)"));
+ QDesktopServices::storageLocation(QDesktopServices::MusicLocation),
+ tr("Music files") + " (*.mp3 *.ogg *.wav *.wma *.flac)");
if (!fileName.isNull()) {
ui.valMusicFile->setText(fileName);
@@ -392,7 +393,7 @@ void EditorApp::on_actionMusicFile_triggered()
void EditorApp::on_actionLyricsFromFile_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
- "",
+ QDir::homePath(),
tr("Text files (*.txt)"));
if (!fileName.isNull()) {
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 11:14:46
|
Module: editor
Branch: master
Commit: ad30b03e91a89861400a0b15e92e7af676790066
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 24 13:13:58 2011 +0200
Handle FFmpeg not being able to open file.
---
notegraphwidget.cc | 6 ++++--
pitchvis.cc | 8 ++++++--
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 740d4c0..d3e4a4c 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -130,8 +130,10 @@ void NoteGraphWidget::timerEvent(QTimerEvent *event)
if (!m_pitch.isNull()) {
QMutexLocker locker(&m_pitch->mutex);
if (m_pitch->newDataAvailable()) setPixmap(QPixmap::fromImage(m_pitch->getImage()));
- if (m_pitch->isFinished()) killTimer(m_analyzeTimer);
- emit analyzeProgress(m_pitch->getXValue(), width());
+ if (m_pitch->isFinished()) {
+ killTimer(m_analyzeTimer);
+ emit analyzeProgress(0, 0); // Reset progressbar
+ } else emit analyzeProgress(m_pitch->getXValue(), width());
}
}
diff --git a/pitchvis.cc b/pitchvis.cc
index d7929a3..20aea67 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -29,10 +29,14 @@ void PitchVis::run()
{
// Initialize FFmpeg decoding
FFmpeg mpeg(false, true, fileName.toStdString(), rate);
- while(std::isnan(mpeg.duration())) msleep(1000); // Wait for ffmpeg to be ready
+ while(std::isnan(mpeg.duration()) || std::isinf(mpeg.duration())) {
+ if (mpeg.terminating()) // Check if FFMPEG has failed
+ return;
+ msleep(1000); // Wait for ffmpeg to be ready
+ }
msleep(1000); // Wait some more
setWidth(mpeg.duration() * rate / step); // Estimation
-
+
curX = 0;
for (std::vector<float> data(step*2); mpeg.audioQueue(&*data.begin(), &*data.end(), curX * step * 2); ++curX) {
// Mix stereo into mono
|
|
From: Tapio V. <aa...@us...> - 2011-01-24 09:09:48
|
Module: editor Branch: master Commit: 6041eec7a308c78f2b2e151425fd77ffa8182850 Author: Tapio Vierros <tap...@gm...> Date: Mon Jan 24 10:40:02 2011 +0200 Preparation for SS XML parsing. Includes some code import from ss_extract. --- songparser-xml.cc | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++ songparser.cc | 5 +- songparser.hh | 6 + 3 files changed, 273 insertions(+), 1 deletions(-) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:57
|
Module: performous
Branch: stereo3d
Commit: 9a4c21b9c1b635ab4baa2e9090a2aa7c1c725450
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 03:04:02 2011 +0100
Added depth to song browser plus minor related tweaks.
---
game/screen_songs.cc | 21 ++++++++++++++-------
themes/default/songs_bg.svg | 9 +++++----
2 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 52af8ff..be904f4 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -142,10 +142,13 @@ void ScreenSongs::drawJukebox() {
}
void ScreenSongs::drawMultimedia() {
- double length = m_audio.getLength();
- double time = clamp(m_audio.getPosition() - config["audio/video_delay"].f(), 0.0, length);
- if (m_songbg.get()) m_songbg->draw(); else m_songbg_default->draw();
- if (m_video.get()) m_video->render(time);
+ {
+ FarTransform ft; // 3D effect
+ double length = m_audio.getLength();
+ double time = clamp(m_audio.getPosition() - config["audio/video_delay"].f(), 0.0, length);
+ if (m_songbg.get()) m_songbg->draw(); else m_songbg_default->draw();
+ if (m_video.get()) m_video->render(time);
+ }
if (!m_jukebox) theme->bg.draw();
}
@@ -248,9 +251,13 @@ void ScreenSongs::drawCovers() {
Song& song = m_songs[baseidx + i];
Surface& s = getCover(song);
// Calculate dimensions for cover and instrument markers
- double diff = (i == 0 ? (0.5 - fabs(shift)) * 0.07 : 0.0);
- double y = 0.27 + 0.5 * diff;
- s.dimensions.middle(-0.2 + 0.17 * (i - shift)).bottom(y - 0.2 * diff).fitInside(0.14 + diff, 0.14 + diff);
+ double diff = (i == 0 ? 2.0 * (0.5 - fabs(shift)) : 0.0); // 0..1 for current cover hilight level
+ double y = 0.26;
+ glutil::PushMatrix pm;
+ glTranslatef(0.0f, 0.0f, -0.05 * (1.0 - diff)); // Move other covers further back
+ double c = 0.6 + 0.4 * diff;
+ glColor3f(c, c, c);
+ s.dimensions.middle(-0.2 + 0.17 * (i - shift)).bottom(y - 0.01 * diff).fitInside(0.15, 0.15);
// Draw the cover normally
s.draw();
// Draw the reflection
diff --git a/themes/default/songs_bg.svg b/themes/default/songs_bg.svg
index 1c201c7..9f9c8ce 100644
--- a/themes/default/songs_bg.svg
+++ b/themes/default/songs_bg.svg
@@ -17,7 +17,7 @@
height="800"
id="svg559"
sodipodi:version="0.32"
- inkscape:version="0.47 r22583"
+ inkscape:version="0.48.0 r9654"
sodipodi:docname="songs_bg.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<metadata
@@ -44,7 +44,7 @@
pagecolor="#ffffff"
id="base"
inkscape:zoom="0.61522534"
- inkscape:cx="445.08607"
+ inkscape:cx="448.33691"
inkscape:cy="383.70921"
inkscape:window-x="0"
inkscape:window-y="29"
@@ -117,9 +117,10 @@
</defs>
<path
style="fill:#ffffff;fill-opacity:0.2739131"
- d="M 49.884998,210 950.115,210 C 966.67129,210 980,223.3225 980,239.87109 l 0,230.25782 C 980,486.6775 966.67129,500 950.115,500 l -533.01146,0 c 0,0 -119.40515,68.26767 -119.40515,68.26767 0,0 -101.15081,-68.26767 -101.15081,-68.26767 0,0 -146.662582,0 -146.662582,0 C 33.328709,500 20,486.6775 20,470.12891 L 20,239.87109 C 20,223.3225 33.328709,210 49.884998,210 z"
+ d="M 49.884998,210 950.115,210 C 966.67129,210 980,223.3225 980,239.87109 l 0,230.25782 C 980,486.6775 966.67129,500 950.115,500 610.93509,500.50433 352.98475,500 49.884998,500 33.328709,500 20,486.6775 20,470.12891 L 20,239.87109 C 20,223.3225 33.328709,210 49.884998,210 z"
id="rect3394"
- sodipodi:nodetypes="cccccccccccc" />
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:24.89476013px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:54
|
Module: performous
Branch: stereo3d
Commit: a86ba551c0518d31e4cb6c3d2720da53222bab1a
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 03:03:06 2011 +0100
Use FarTransform
---
game/screen_sing.cc | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 0f8e7b2..d12b5e6 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -424,10 +424,7 @@ void ScreenSing::draw() {
// Rendering starts
{
- glutil::PushMatrix pm;
- float s = 70.0f;
- glTranslatef(0.0f, 0.0f, -90.0f);
- glScalef(s, s, s);
+ FarTransform ft;
double ar = arMax;
// Background image
if (m_background) {
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:52
|
Module: performous
Branch: stereo3d
Commit: 477655db8f247c402e0967327f3c5504fbdcfeb0
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 03:02:38 2011 +0100
Add scaling to projection matrix so that 2d translations are easier, changed all 2d translations accordingly; added FarTransform which is a RAII object for drawing backgrounds on the far plane but in fullscreen size.
---
game/dancegraph.cc | 2 +-
game/guitargraph.cc | 2 +-
game/screenmanager.cc | 4 ++--
game/video_driver.cc | 28 ++++++++++++++++++++--------
game/video_driver.hh | 13 +++++++++++--
5 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/game/dancegraph.cc b/game/dancegraph.cc
index f37ed39..eabd84c 100644
--- a/game/dancegraph.cc
+++ b/game/dancegraph.cc
@@ -416,7 +416,7 @@ void DanceGraph::draw(double time) {
double frac = 0.75; // Adjustable: 1.0 means fully separated, 0.0 means fully attached
// Some matrix magic to get the viewport right
glutil::PushMatrixMode pmm(GL_PROJECTION);
- glTranslatef((2.0 * frac) * offsetX, 0.0f, 0.0f);
+ glTranslatef(frac * offsetX, 0.0f, 0.0f);
glutil::PushMatrixMode pmb(GL_MODELVIEW);
glTranslatef((1.0 - frac) * offsetX, dimensions.y1(), 0.0f);
float temp_s = dimensions.w() / 8.0f; // Allow for 8 pads to fit on a track
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 4a6f9c5..55ba0f7 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -796,7 +796,7 @@ void GuitarGraph::draw(double time) {
{ // Translate, rotate and scale to place
double frac = 0.75; // Adjustable: 1.0 means fully separated, 0.0 means fully attached
glutil::PushMatrixMode pmm(GL_PROJECTION);
- glTranslatef(frac * 2.0 * offsetX, 0.0f, 0.0f);
+ glTranslatef(frac * offsetX, 0.0f, 0.0f);
glutil::PushMatrixMode pmb(GL_MODELVIEW);
glTranslatef((1.0 - frac) * offsetX, dimensions.y2(), 0.0f);
// Do some jumping for drums
diff --git a/game/screenmanager.cc b/game/screenmanager.cc
index c702966..e28dc19 100644
--- a/game/screenmanager.cc
+++ b/game/screenmanager.cc
@@ -46,7 +46,7 @@ void ScreenManager::drawScreen() {
{
glViewport(0, 0, 1920, 540);
glutil::PushMatrixMode pp(GL_PROJECTION);
- glTranslatef(0.04f, 0.0f, 0.0f);
+ glTranslatef(0.02f, 0.0f, 0.0f);
glutil::PushMatrixMode pmv(GL_MODELVIEW);
glTranslatef(-0.02f, 0.0f, 0.0f);
//UseFBO fbo(m_fbo);
@@ -56,7 +56,7 @@ void ScreenManager::drawScreen() {
{
glViewport(0, 540, 1920, 540);
glutil::PushMatrixMode pp(GL_PROJECTION);
- glTranslatef(-0.04f, 0.0f, 0.0f);
+ glTranslatef(-0.02f, 0.0f, 0.0f);
glutil::PushMatrixMode pmv(GL_MODELVIEW);
glTranslatef(0.02f, 0.0f, 0.0f);
//UseFBO fbo(m_fbo);
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 97da558..eb505f1 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -1,7 +1,6 @@
#include "video_driver.hh"
#include "config.hh"
-#include "glutil.hh"
#include "fs.hh"
#include "image.hh"
#include "util.hh"
@@ -31,6 +30,11 @@ namespace {
int m_value;
};
+ // stump: under MSVC, near and far are #defined to nothing for compatibility with ancient code, hence the underscores.
+ const float near_ = 0.1f; // This determines the near clipping distance (must be > 0)
+ const float far_ = 110.0f; // How far away can things be seen
+ const float z0 = 1.5f; // This determines FOV: the value is your distance from the monitor (the unit being the width of the Performous window)
+
}
unsigned int screenW() { return s_width; }
@@ -67,7 +71,7 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
Window::~Window() { }
void Window::blank() {
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Window::swap() {
@@ -137,17 +141,17 @@ void Window::resize() {
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
- // Set projection
+ // Setup the projection matrix for 2D translates
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float h = virtH();
- // stump: under MSVC, near and far are #defined to nothing for compatibility with ancient code, hence the underscores.
- const float near_ = 0.5f; // This determines the near clipping distance (must be > 0)
- const float far_ = 100.0f; // How far away can things be seen
- const float z0 = 1.5f; // This determines FOV: the value is your distance from the monitor (the unit being the width of the Performous window)
- // Set model-view matrix
+ // OpenGL normalized coordinates go from -1 to 1, change scale so that our 2D translates can use the Performous normalized coordinates instead
+ glScalef(2.0f, 2.0f / h, 1.0f);
+ // Note: we do the frustum on MODELVIEW so that 2D positioning can be done via projection matrix.
+ // glTranslatef on that will move the image, not the camera (i.e. far-away and nearby objects move the same amount)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+ glScalef(0.5f, 0.5f * h, 1.0f); // Invert the scaling done on projection matrix
const float f = near_ / z0;
glFrustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_);
glTranslatef(0.0f, 0.0f, -z0); // Move back the world so that z = 0.0f is the monitor surface
@@ -155,3 +159,11 @@ void Window::resize() {
glutil::GLErrorChecker glerror("Window::resize");
}
+FarTransform::FarTransform() {
+ float z = far_ - 0.1f; // Very near the far plane but just a bit closer to avoid accidental clipping
+ float s = z / z0; // Scale the image so that it looks the same size
+ s *= 1.04; // A bit more for stereo3d (avoid black borders)
+ glTranslatef(0.0f, 0.0f, -z + z0); // Very near the farplane
+ glScalef(s, s, s);
+}
+
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 79c24c9..131c3ef 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -1,6 +1,7 @@
#pragma once
#include "glshader.hh"
+#include "glutil.hh"
#include <boost/scoped_ptr.hpp>
unsigned int screenW();
@@ -9,9 +10,17 @@ static inline float virtH() { return float(screenH()) / screenW(); }
struct SDL_Surface;
+/// Performs a GL transform for displaying background image at far distance
+class FarTransform {
+public:
+ FarTransform();
+private:
+ glutil::PushMatrix pm;
+};
+
/// handles the window
class Window {
- public:
+public:
/// constructor
Window(unsigned int windowW, unsigned int windowH, bool fullscreen);
/// destructor
@@ -39,7 +48,7 @@ class Window {
/// take a screenshot
void screenshot();
- private:
+private:
SDL_Surface* screen;
unsigned int m_windowW, m_windowH;
unsigned int m_fsW, m_fsH;
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:49
|
Module: performous
Branch: stereo3d
Commit: 9f0e26b2fc83582cbe20e039cafcf849c15a3ee5
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 00:46:05 2011 +0100
Add 3D to message dialogs
---
game/dialog.hh | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/game/dialog.hh b/game/dialog.hh
index 65b7d8e..b3e63a8 100644
--- a/game/dialog.hh
+++ b/game/dialog.hh
@@ -18,6 +18,8 @@ class Dialog {
}
/// draws dialogue
void draw() {
+ glutil::PushMatrix pm;
+ glTranslatef(0.0f, 0.0f, 0.1f); // Raise a bit in 3D
m_dialog.draw();
m_svgText.draw(m_text);
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:47
|
Module: performous
Branch: stereo3d
Commit: 7f57f0db64a7cfe6040a5a5d31c64026ca122150
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 24 00:45:07 2011 +0100
Proper calculation of frustum instead of arbitrary multiplier
---
game/video_driver.cc | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/game/video_driver.cc b/game/video_driver.cc
index c501639..97da558 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -142,14 +142,15 @@ void Window::resize() {
glLoadIdentity();
float h = virtH();
// stump: under MSVC, near and far are #defined to nothing for compatibility with ancient code, hence the underscores.
- const float near_ = 1.5f; // This determines FOV: the value is your distance from the monitor (the unit being the width of the Performous window)
+ const float near_ = 0.5f; // This determines the near clipping distance (must be > 0)
const float far_ = 100.0f; // How far away can things be seen
+ const float z0 = 1.5f; // This determines FOV: the value is your distance from the monitor (the unit being the width of the Performous window)
// Set model-view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- const float f = 0.9f; // Avoid texture surface being exactly at the near plane (MacOSX fix)
- glFrustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, f * near_, far_);
- glTranslatef(0.0f, 0.0f, -near_); // So that z = 0.0f is still on monitor surface
+ const float f = near_ / z0;
+ glFrustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_);
+ glTranslatef(0.0f, 0.0f, -z0); // Move back the world so that z = 0.0f is the monitor surface
// Check for OpenGL errors
glutil::GLErrorChecker glerror("Window::resize");
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-24 02:33:42
|
Module: performous
Branch: stereo3d
Commit: c18e8012f5c2f51334e1f7c99bbc1138ccc3743c
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jan 21 23:55:57 2011 +0100
Revert "Lyric text rendering in 3D instead of zoom (BUGGY HACK)"
This reverts commit 733eb048a4cd472d2d60a687c0f4bcf2b7893773.
---
game/opengl_text.cc | 7 +------
game/video_driver.cc | 2 +-
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/game/opengl_text.cc b/game/opengl_text.cc
index f2c95d0..098f022 100644
--- a/game/opengl_text.cc
+++ b/game/opengl_text.cc
@@ -244,17 +244,12 @@ void SvgTxtTheme::draw(std::vector<TZoomText> const& _text, float alpha) {
TexCoords tex;
double factor = _text[i].factor;
Color color;
- glutil::PushMatrix pm;
if (factor == 1.0) color = Color(1.0f, 1.0f, 1.0f, alpha);
else {
color = Color(m_text_highlight.fill_col.r, m_text_highlight.fill_col.g, m_text_highlight.fill_col.b, alpha);
- glTranslatef(0.0f, 0.0f, factor - 1.0f);
+ dim.fixedWidth(dim.w() * factor);
}
{
- glutil::PushMatrixMode ppm(GL_PROJECTION);
- glTranslatef(2.0f * dim.xc(), -4.0f * dim.yc(), 0.0f);
- dim.middle(0.0f).center(0.0f);
- glutil::PushMatrixMode(GL_MODELVIEW);
glutil::Color c(color);
m_opengl_text[i].draw(dim, tex);
}
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 187e405..c501639 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -147,7 +147,7 @@ void Window::resize() {
// Set model-view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- const float f = 0.8f; // Add some margin in front of nearplane (needed for 3D effects and OSX to avoid clipping)
+ const float f = 0.9f; // Avoid texture surface being exactly at the near plane (MacOSX fix)
glFrustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, f * near_, far_);
glTranslatef(0.0f, 0.0f, -near_); // So that z = 0.0f is still on monitor surface
// Check for OpenGL errors
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-23 19:39:12
|
Module: editor Branch: master Commit: c2ac074bcfedd799a668ebf76e0b7b6fcb0922f9 Author: Lasse Karkkainen <tro...@tr...> Date: Sun Jan 23 20:38:59 2011 +0100 PitchVis almost complete rewrite for now rendering style + related changes and fixes --- pitch.cc | 29 +++---------- pitch.hh | 5 +- pitchvis.cc | 133 ++++++++++++++++++++++++++++------------------------------- pitchvis.hh | 6 +- 4 files changed, 76 insertions(+), 97 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2011-01-23 13:38:21
|
Module: performous
Branch: master
Commit: f340c6f12b095347966dc535a612f8cbfba4f1d7
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Jan 23 14:37:59 2011 +0100
Reverted manually bf2c4bdf (practice drum mode not used at all) to simplify guitargraph
---
game/guitargraph.cc | 42 +++++-------------------------------------
game/guitargraph.hh | 4 +---
game/screen_sing.cc | 12 +++---------
game/screen_sing.hh | 4 +---
4 files changed, 10 insertions(+), 52 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 61cb1b0..51cd3d2 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -93,7 +93,7 @@ void GuitarGraph::initDrums() {
//m_samples.push_back("drum tom2");
}
-GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number, bool practmode):
+GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number):
InstrumentGraph(audio, song, drums ? input::DRUMS : input::GUITAR),
m_tail(getThemePath("tail.svg")),
m_tail_glow(getThemePath("tail_glow.svg")),
@@ -105,7 +105,6 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
m_neckglowColor(),
m_drums(drums),
m_use3d(config["graphic/3d_notes"].b()),
- m_practmode(practmode),
m_level(),
m_track_index(m_instrumentTracks.end()),
m_dfIt(m_drumfills.end()),
@@ -120,7 +119,6 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
m_soloTotal(),
m_soloScore(),
m_solo(),
- m_practHold(false),
m_hasTomTrack(false),
m_whammy(0)
{
@@ -413,31 +411,14 @@ void GuitarGraph::engine() {
// Countdown to start
handleCountdown(time, time < getNotesBeginTime() ? getNotesBeginTime() : m_jointime+1);
- // FIXME: this is a band aid to release m_practHold
- // this may happen in conjunction with the regular pause feature
- if (m_practHold && !m_audio.isPaused()) m_practHold = false;
-
// Skip missed notes
// we hold the note a litle bit *before* they go out of the tolerance window
// this is important in order for the hit-detection to still accept the notes
// FIXME: need to confirm that this timing is reliable,
// if a note gets marked as 'past' completing the chord does not re-start the song
- double past = time - maxTolerance + (m_practmode ? 0.05 : 0.0);
- while (!m_practHold && m_chordIt != m_chords.end() && m_chordIt->begin < past) {
+ while (m_chordIt != m_chords.end() && m_chordIt->begin + maxTolerance < time) {
if ( (m_drums && m_chordIt->status != m_chordIt->polyphony)
- || (!m_drums && m_chordIt->status == 0) ) {
- endStreak();
- if (m_practmode && !dead()) {
- // in practice mode hold the chord here
- // m_chordIt must not change until finishing the chord
- m_audio.seekPos(m_chordIt->begin);
- m_audio.pause(true);
- m_practHold = true;
- endStreak();
- std::cout << "practice: hold chord at " << m_chordIt->begin << ", status = "<< m_chordIt->status << std::endl;
- break;
- }
- }
+ || (!m_drums && m_chordIt->status == 0) ) endStreak();
// Calculate solo total score
if (m_solo) { m_soloScore += m_chordIt->score; m_soloTotal += m_chordIt->polyphony * points(0);
// Solo just ended?
@@ -451,17 +432,6 @@ void GuitarGraph::engine() {
++m_chordIt;
}
- // just finished a chord in practice mode
- if (m_practHold &&
- ( (m_drums && m_chordIt->status == m_chordIt->polyphony)
- || (!m_drums && m_chordIt->status != 0) ) ) {
- // now we have completed the chord
- // m_chordIt must not change from holding the chord until we get here
- if (m_audio.isPaused()) m_audio.togglePause();
- m_practHold = false;
- std::cout << "practice: finish chord at " << m_chordIt->begin << std::endl;
- }
-
if (difficulty_changed) m_dead = 0; // if difficulty is changed, m_dead would get incorrect
// Adjust the correctness value
if (!m_events.empty() && m_events.back().type == 0) m_correctness.setTarget(0.0, true);
@@ -649,18 +619,16 @@ void GuitarGraph::drumHit(double time, int fret) {
// in kiddy mode we don't care about the correct pad
// all that matters is that there is still a missing note in that chord
if (m_chordIt->status == m_chordIt->polyphony) continue;
- } else if ((!it->dur[fret]) || (m_notes[it->dur[fret]])) continue; // invalid fret/hit or already played
+ } else if (m_notes[it->dur[fret]]) continue; // invalid fret/hit or already played
double error = std::abs(it->begin - time);
if (error < tolerance) {
best = it;
tolerance = error;
signed_error = it->begin - time;
- if (m_practHold) break; // during practice hold the chord will always be m_chordIt
}
}
- if ((best == m_chords.end())
- || (m_practHold && best != m_chordIt)) fail(time, fret); // None found
+ if (best == m_chords.end()) fail(time, fret); // None found
else {
// Skip all chords earlier than the best fit chord
for (; best != m_chordIt; ++m_chordIt) {
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index f0dc946..313b744 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -46,7 +46,7 @@ static inline bool operator==(Chord const& a, Chord const& b) {
class GuitarGraph: public InstrumentGraph {
public:
/// constructor
- GuitarGraph(Audio& audio, Song const& song, bool drums, int number, bool practmode=false);
+ GuitarGraph(Audio& audio, Song const& song, bool drums, int number);
/** draws GuitarGraph
* @param time at which time to draw
*/
@@ -99,7 +99,6 @@ class GuitarGraph: public InstrumentGraph {
// Flags
bool m_drums; /// are we using drums?
bool m_use3d; /// are we using 3d?
- bool m_practmode; /// switch to enable practice mode
// Track stuff
enum Difficulty {
@@ -154,7 +153,6 @@ class GuitarGraph: public InstrumentGraph {
double m_soloTotal; /// maximum solo score
double m_soloScore; /// score during solo
bool m_solo; /// are we currently playing a solo
- bool m_practHold; /// true if holding a chord during practice
bool m_hasTomTrack; /// true if the track has at least one tom track
double m_whammy; /// whammy value for pitch shift
};
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 525f035..8febec1 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -30,7 +30,6 @@ namespace {
}
void ScreenSing::enter() {
- //m_practmode = true; // un-comment this line to play with practice mode. temporary, of course!
ScreenManager* sm = ScreenManager::getSingletonPtr();
sm->loading(_("Loading theme..."), 0.0);
theme.reset(new ThemeSing());
@@ -104,7 +103,7 @@ void ScreenSing::enter() {
if (type == 3) break;
}
if (type == 0) m_dancers.push_back(new DanceGraph(m_audio, *m_song));
- else m_instruments.push_back(new GuitarGraph(m_audio, *m_song, type == 2, idx, m_practmode));
+ else m_instruments.push_back(new GuitarGraph(m_audio, *m_song, type == 2, idx));
++idx;
} catch (input::NoDevError&) {
++type;
@@ -508,13 +507,8 @@ void ScreenSing::draw() {
}
if (m_audio.isPaused()) {
- if (!m_practmode) {
- //m_pause_icon->dimensions.middle().center().fixedWidth(.32);
- //m_pause_icon->draw();
- } else {
- // we get here when the song is on hold during practice
- // TODO: display some (small) info screen here
- }
+ //m_pause_icon->dimensions.middle().center().fixedWidth(.32);
+ //m_pause_icon->draw();
}
// Menus on top of everything
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index 5df5af6..0b63066 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -49,8 +49,7 @@ class ScreenSing: public Screen {
public:
/// constructor
ScreenSing(std::string const& name, Audio& audio, Database& database, Backgrounds& bgs):
- Screen(name), m_audio(audio), m_database(database), m_backgrounds(bgs), m_latencyAV(), m_only_singers_alive(true), m_practmode(false),
- m_selectedTrack(TrackName::LEAD_VOCAL)
+ Screen(name), m_audio(audio), m_database(database), m_backgrounds(bgs), m_latencyAV(), m_only_singers_alive(true), m_selectedTrack(TrackName::LEAD_VOCAL)
{}
void enter();
void exit();
@@ -94,7 +93,6 @@ class ScreenSing: public Screen {
boost::shared_ptr<ThemeSing> theme;
AnimValue m_quitTimer;
bool m_only_singers_alive;
- bool m_practmode;
std::string m_selectedTrack;
std::string m_selectedTrackLocalized;
ConfigItem m_vocalTrackOpts;
|
|
From: Yoda-JM <yo...@us...> - 2011-01-23 12:25:48
|
Module: performous
Branch: master
Commit: a8c99571148d20f31272095a4fbea7d01b271bf0
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Jan 23 13:25:28 2011 +0100
Started some simple guitargraph regactoring
---
game/guitargraph.cc | 133 +++++++++++++++++++++++++++++++-------------------
game/guitargraph.hh | 8 +++-
2 files changed, 89 insertions(+), 52 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index d3422d7..61cb1b0 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -59,6 +59,40 @@ namespace {
inline float blend(float a, float b, float f) { return a*f + b*(1.0f-f); }
}
+void GuitarGraph::initGuitar() {
+ // Copy all tracks of guitar types (not DRUMS and not KEYBOARD) to m_instrumentTracks
+ for (InstrumentTracks::const_iterator it = m_song.instrumentTracks.begin(); it != m_song.instrumentTracks.end(); ++it) {
+ std::string index = it->first;
+ if (index != TrackName::DRUMS && index != TrackName::KEYBOARD) m_instrumentTracks[index] = &it->second;
+ }
+ if (m_instrumentTracks.empty()) throw std::logic_error("No guitar tracks found");
+
+ // Adding fail samples
+ 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");
+}
+
+void GuitarGraph::initDrums() {
+ // Copy all tracks of drum type to m_instrumentTracks
+ for (InstrumentTracks::const_iterator it = m_song.instrumentTracks.begin(); it != m_song.instrumentTracks.end(); ++it) {
+ std::string index = it->first;
+ if (index == TrackName::DRUMS) m_instrumentTracks[index] = &it->second;
+ }
+ if (m_instrumentTracks.empty()) throw std::logic_error("No drum tracks found");
+
+ // Adding fail samples
+ 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");
+}
+
GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number, bool practmode):
InstrumentGraph(audio, song, drums ? input::DRUMS : input::GUITAR),
m_tail(getThemePath("tail.svg")),
@@ -90,33 +124,17 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
m_hasTomTrack(false),
m_whammy(0)
{
- // Copy all tracks of supported types (either drums or non-drums) to m_instrumentTracks
- for (InstrumentTracks::const_iterator it = m_song.instrumentTracks.begin(); it != m_song.instrumentTracks.end(); ++it) {
- std::string index = it->first;
- if (m_drums == (index == TrackName::DRUMS)) m_instrumentTracks[index] = &it->second;
+ if(m_drums) {
+ initDrums();
+ } else {
+ initGuitar();
}
- if (m_instrumentTracks.empty()) throw std::logic_error(m_drums ? "No drum tracks found" : "No guitar tracks found");
// Load 3D fret objects
m_fretObj.load(getThemePath("fret.obj"));
m_tappableObj.load(getThemePath("fret_tap.obj"));
// 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()));
- if (m_drums) {
- 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("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 (size_t i = 0; i < max_panels; ++i) {
m_pressed_anim[i].setRate(5.0);
m_holds[i] = 0;
@@ -135,43 +153,55 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
setupJoinMenu();
}
+void GuitarGraph::setupJoinMenuDifficulty() {
+ ConfigItem::OptionList ol;
+ int cur = 0;
+ // Add difficulties to the option list
+ for (int level = 0; level < DIFFICULTYCOUNT; ++level) {
+ if (difficulty(Difficulty(level), true)) {
+ ol.push_back(boost::lexical_cast<std::string>(level));
+ if (Difficulty(level) == m_level) cur = ol.size()-1;
+ }
+ }
+ m_selectedDifficulty = ConfigItem(ol); // Create a ConfigItem from the option list
+ m_selectedDifficulty.select(cur); // Set the selection to current level
+ m_menu.add(MenuOption("", _("Select difficulty"), &m_selectedDifficulty)); // MenuOption that cycles the options
+ m_menu.back().setDynamicName(m_difficultyOpt); // Set the title to be dynamic
+}
+
+void GuitarGraph::setupJoinMenuDrums() {
+ setupJoinMenuDifficulty();
+ m_menu.add(MenuOption(_("Lefty-mode"), "", &m_leftymode));
+ m_menu.back().setDynamicComment(m_leftyOpt);
+}
+
+void GuitarGraph::setupJoinMenuGuitar() {
+ ConfigItem::OptionList ol;
+ int cur = 0;
+ // Add tracks to option list
+ for (InstrumentTracksConstPtr::const_iterator it = m_instrumentTracks.begin(); it != m_instrumentTracks.end(); ++it) {
+ ol.push_back(it->first);
+ if (m_track_index->first == it->first) cur = ol.size()-1; // Find the index of current track
+ }
+ m_selectedTrack = ConfigItem(ol); // Create a ConfigItem from the option list
+ m_selectedTrack.select(cur); // Set the selection to current track
+ m_menu.add(MenuOption("", _("Select track"), &m_selectedTrack)); // MenuOption that cycles the options
+ m_menu.back().setDynamicName(m_trackOpt); // Set the title to be dynamic
+ setupJoinMenuDifficulty();
+ m_menu.add(MenuOption(_("Lefty-mode"), "", &m_leftymode));
+ m_menu.back().setDynamicComment(m_leftyOpt);
+}
void GuitarGraph::setupJoinMenu() {
m_menu.clear();
updateJoinMenu();
// Populate root menu
m_menu.add(MenuOption(_("Ready!"), _("Start performing!")));
- // Create track option only for guitars
- if (!m_drums) {
- ConfigItem::OptionList ol;
- int cur = 0;
- // Add tracks to option list
- for (InstrumentTracksConstPtr::const_iterator it = m_instrumentTracks.begin(); it != m_instrumentTracks.end(); ++it) {
- ol.push_back(it->first);
- if (m_track_index->first == it->first) cur = ol.size()-1; // Find the index of current track
- }
- m_selectedTrack = ConfigItem(ol); // Create a ConfigItem from the option list
- m_selectedTrack.select(cur); // Set the selection to current track
- m_menu.add(MenuOption("", _("Select track"), &m_selectedTrack)); // MenuOption that cycles the options
- m_menu.back().setDynamicName(m_trackOpt); // Set the title to be dynamic
- }
- { // Create difficulty opt
- ConfigItem::OptionList ol;
- int cur = 0;
- // Add difficulties to the option list
- for (int level = 0; level < DIFFICULTYCOUNT; ++level) {
- if (difficulty(Difficulty(level), true)) {
- ol.push_back(boost::lexical_cast<std::string>(level));
- if (Difficulty(level) == m_level) cur = ol.size()-1;
- }
- }
- m_selectedDifficulty = ConfigItem(ol); // Create a ConfigItem from the option list
- m_selectedDifficulty.select(cur); // Set the selection to current level
- m_menu.add(MenuOption("", _("Select difficulty"), &m_selectedDifficulty)); // MenuOption that cycles the options
- m_menu.back().setDynamicName(m_difficultyOpt); // Set the title to be dynamic
+ if(m_drums) {
+ setupJoinMenuDrums();
+ } else {
+ setupJoinMenuGuitar();
}
- m_menu.add(MenuOption(_("Lefty-mode"), "", &m_leftymode));
- m_menu.back().setDynamicComment(m_leftyOpt);
m_menu.add(MenuOption(_("Quit"), _("Exit to song browser"), "Songs"));
}
@@ -188,6 +218,7 @@ void GuitarGraph::updateNeck() {
// TODO: Optimize with texture cache
std::string index = m_track_index->first;
if (index == TrackName::DRUMS) m_neck.reset(new Texture(getThemePath("drumneck.svg")));
+ else if (index == TrackName::KEYBOARD) m_neck.reset(new Texture(getThemePath("guitarneck.svg")));
else if (index == TrackName::BASS) m_neck.reset(new Texture(getThemePath("bassneck.svg")));
else m_neck.reset(new Texture(getThemePath("guitarneck.svg")));
}
@@ -226,7 +257,7 @@ std::string GuitarGraph::getDifficultyString() const {
/// Get a string id for track and difficulty
std::string GuitarGraph::getModeId() const {
return m_track_index->first + " - " + diffv[m_level].name
- + (m_drums && m_input.isKeyboard() ? " (kbd)" : "");
+ + (m_input.isKeyboard() ? " (kbd)" : "");
}
/// Cycle through difficulties
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index a1ab5cf..f0dc946 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -50,7 +50,6 @@ class GuitarGraph: public InstrumentGraph {
/** draws GuitarGraph
* @param time at which time to draw
*/
- void updateNeck();
void draw(double time);
void engine();
bool dead() const;
@@ -62,7 +61,14 @@ class GuitarGraph: public InstrumentGraph {
double getWhammy() const { return m_whammy; }
private:
+ // refactoring methods
+ void initDrums();
+ void initGuitar();
+ void setupJoinMenuDifficulty();
+ void setupJoinMenuDrums();
+ void setupJoinMenuGuitar();
// Engine / scoring utils
+ void updateNeck();
bool canActivateStarpower() { return (m_starmeter > 6000); }
void activateStarpower();
void errorMeter(float error);
|
|
From: Yoda-JM <yo...@us...> - 2011-01-22 15:53:10
|
Module: performous Branch: master Commit: 53a912fa44275ffdd9c9b6bb1eb57458a0be85d8 Author: Vincent Le Ligeour <yo...@us...> Date: Sat Jan 22 16:52:29 2011 +0100 Made mididrums mapping configurable Conflicts: game/main.cc --- data/CMakeLists.txt | 2 + data/mididrums.xml | 75 +++++++++++++++++++++++++++ game/joystick.cc | 139 +++++++++++++++++++-------------------------------- game/joystick.hh | 3 +- game/main.cc | 4 +- 5 files changed, 134 insertions(+), 89 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2011-01-22 15:53:08
|
Module: performous Branch: master Commit: dcdb3a646267e66aa51dc9c86e6d2b7a418ba25d Author: Vincent Le Ligeour <yo...@us...> Date: Sat Jan 22 16:48:06 2011 +0100 Added some more keyboard management --- data/controllers.xml | 12 +++++++ data/schema.xml | 6 ++++ game/joystick.cc | 66 +++++++++++++++++++++++++++++++++++++-- game/joystick.hh | 16 ++++++++-- game/screen_songs.cc | 24 ++++++++++++-- game/song.hh | 3 +- game/songs.cc | 1 + themes/default/instruments.svg | 30 +++++++++++++++--- 8 files changed, 141 insertions(+), 17 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2011-01-22 14:41:26
|
Module: performous
Branch: master
Commit: 2d8629551ef3548ef0cb35d0ff47aa6762c1fac9
Author: Vincent Le Ligeour <yo...@us...>
Date: Sat Jan 22 15:41:09 2011 +0100
Added keyboard track name
---
game/song.hh | 1 +
game/songparser-ini.cc | 3 +++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/game/song.hh b/game/song.hh
index 3250442..87b3d76 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -26,6 +26,7 @@ namespace TrackName {
const std::string GUITAR_COOP = "Coop guitar";
const std::string GUITAR_RHYTHM = "Rhythm guitar";
const std::string BASS = "Bass";
+ const std::string KEYBOARD = "Keyboard";
const std::string DRUMS = "Drums";
const std::string LEAD_VOCAL = "Vocals";
const std::string HARMONIC_1 = "Harmonic 1";
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index c46f476..8548f15 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -96,6 +96,7 @@ void SongParser::iniParseHeader() {
boost::regex audiofile_guitar("(guitar\\.ogg)$", boost::regex_constants::icase);
boost::regex audiofile_drums("(drums\\.ogg)$", boost::regex_constants::icase);
boost::regex audiofile_bass("(rhythm\\.ogg)$", boost::regex_constants::icase);
+ boost::regex audiofile_keyboard("(keyboard\\.ogg)$", boost::regex_constants::icase);
boost::regex audiofile_vocals("(vocals\\.ogg)$", boost::regex_constants::icase);
boost::regex audiofile_other("(.*\\.ogg)$", boost::regex_constants::icase);
boost::cmatch match;
@@ -112,6 +113,8 @@ void SongParser::iniParseHeader() {
testAndAdd(s, TrackName::GUITAR, name);
} else if (regex_match(name.c_str(), match, audiofile_bass)) {
testAndAdd(s, TrackName::BASS, name);
+ } else if (regex_match(name.c_str(), match, audiofile_keyboard)) {
+ testAndAdd(s, TrackName::KEYBOARD, name);
} else if (regex_match(name.c_str(), match, audiofile_drums)) {
testAndAdd(s, TrackName::DRUMS, name);
} else if (regex_match(name.c_str(), match, audiofile_vocals)) {
|
|
From: Yoda-JM <yo...@us...> - 2011-01-22 14:35:05
|
Module: performous
Branch: master
Commit: 56bf3d66d16bff9e8ddbf41a780eae4252fbea43
Author: Vincent Le Ligeour <yo...@us...>
Date: Sat Jan 22 15:34:41 2011 +0100
Added pro bass track detection
---
game/songparser-ini.cc | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index ca64598..c46f476 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -53,6 +53,7 @@ namespace {
else if (name == "REAL_KEYS_H") return false; // TODO: RB3 pro keyboard hard track
else if (name == "REAL_KEYS_M") return false; // TODO: RB3 pro keyboard medium track
else if (name == "REAL_KEYS_E") return false; // TODO: RB3 pro keyboard easy track
+ else if (name == "REAL_BASS") return false; // TODO: RB3 pro bass track
else if (name == "REAL_GUITAR") return false; // TODO: RB3 pro guitar 17 frets (Mustang) track
else if (name == "REAL_GUITAR_22") return false; // TODO: RB3 pro guitar 22 frets (Squier) track
else return false;
|
|
From: Yoda-JM <yo...@us...> - 2011-01-22 14:32:07
|
Module: performous
Branch: master
Commit: d921dabc269a5bd9b4b1e3c500e4f9ca32ab2cd8
Author: Vincent Le Ligeour <yo...@us...>
Date: Sat Jan 22 15:31:46 2011 +0100
Added pro guitar and pro keyboard hard/medium/easy tracks
---
game/songparser-ini.cc | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index 6d353d5..ca64598 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -43,12 +43,18 @@ namespace {
else if (name == "DRUMS") name = TrackName::DRUMS;
else if (name == "BASS") name = TrackName::BASS;
else if (name == "KEYS") return false; // TODO: RB3 5 lane keyboard track
- else if (name == "REAL_KEYS_X") return false; // TODO: RB3 pro keyboard track
else if (name == "GUITAR") name = TrackName::GUITAR;
else if (name == "VOCALS") name = TrackName::LEAD_VOCAL;
else if (name == "HARM1") name = TrackName::HARMONIC_1;
else if (name == "HARM2") name = TrackName::HARMONIC_2;
else if (name == "HARM3") name = TrackName::HARMONIC_3;
+ // expert stuffs
+ else if (name == "REAL_KEYS_X") return false; // TODO: RB3 pro keyboard expert track
+ else if (name == "REAL_KEYS_H") return false; // TODO: RB3 pro keyboard hard track
+ else if (name == "REAL_KEYS_M") return false; // TODO: RB3 pro keyboard medium track
+ else if (name == "REAL_KEYS_E") return false; // TODO: RB3 pro keyboard easy track
+ else if (name == "REAL_GUITAR") return false; // TODO: RB3 pro guitar 17 frets (Mustang) track
+ else if (name == "REAL_GUITAR_22") return false; // TODO: RB3 pro guitar 22 frets (Squier) track
else return false;
return true;
}
|
|
From: Yoda-JM <yo...@us...> - 2011-01-22 12:37:06
|
Module: performous Branch: master Commit: 98bc4473cb9488482f36d2703889186c663cda50 Author: Vincent Le Ligeour <yo...@us...> Date: Sat Jan 22 13:36:07 2011 +0100 Added keyboard and pro-keyboard track names according to http://creators.rockband.com/docs/Authoring --- game/songparser-ini.cc | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc index 398b092..6d353d5 100644 --- a/game/songparser-ini.cc +++ b/game/songparser-ini.cc @@ -42,6 +42,8 @@ namespace { else if (name == "DRUM") name = TrackName::DRUMS; else if (name == "DRUMS") name = TrackName::DRUMS; else if (name == "BASS") name = TrackName::BASS; + else if (name == "KEYS") return false; // TODO: RB3 5 lane keyboard track + else if (name == "REAL_KEYS_X") return false; // TODO: RB3 pro keyboard track else if (name == "GUITAR") name = TrackName::GUITAR; else if (name == "VOCALS") name = TrackName::LEAD_VOCAL; else if (name == "HARM1") name = TrackName::HARMONIC_1; |
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-21 14:36:11
|
Module: editor
Branch: master
Commit: 38abe0e70949ac6661e921b8674a1a45d890b6af
Author: Lasse Karkkainen <tro...@tr...>
Date: Fri Jan 21 15:35:53 2011 +0100
Cleanup and attempts to fix unreliability
---
notegraphwidget.cc | 10 ++--
pitchvis.cc | 147 +++++++++++++++++++++++++++-------------------------
pitchvis.hh | 4 +-
3 files changed, 83 insertions(+), 78 deletions(-)
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index 1eee744..740d4c0 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -128,12 +128,10 @@ void NoteGraphWidget::timerEvent(QTimerEvent *event)
{
(void)event;
if (!m_pitch.isNull()) {
- if (m_pitch->newDataAvailable())
- setPixmap(QPixmap::fromImage(m_pitch->getImage()));
- if (m_pitch->isFinished()) {
- killTimer(m_analyzeTimer);
- emit analyzeProgress(width(), width());
- } else emit analyzeProgress(m_pitch->getXValue(), width());
+ QMutexLocker locker(&m_pitch->mutex);
+ if (m_pitch->newDataAvailable()) setPixmap(QPixmap::fromImage(m_pitch->getImage()));
+ if (m_pitch->isFinished()) killTimer(m_analyzeTimer);
+ emit analyzeProgress(m_pitch->getXValue(), width());
}
}
diff --git a/pitchvis.cc b/pitchvis.cc
index 55f3cb0..e41b116 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -1,5 +1,5 @@
-#include "pitchvis.hh"
+#include "pitchvis.hh"
#include "pitch.hh"
#include "ffmpeg.hh"
#include <fstream>
@@ -30,82 +30,89 @@ PitchVis::PitchVis(QString const& filename, QWidget *parent)
void PitchVis::run()
{
- // Initialize FFmpeg decoding
- FFmpeg mpeg(false, true, fileName.toStdString(), 44100);
- while(std::isnan(mpeg.duration())); // Wait for ffmpeg to be ready
- msleep(1000); // Wait some more
-
- unsigned width = mpeg.duration() * 44100 / step;
- img.resize(width * height);
- Analyzer analyzer(44100, "");
-
- QLabel *ngw = qobject_cast<QLabel*>(QWidget::parent());
- if (ngw) {
- ngw->setFixedSize(width, height);
- } else return;
-
- // Create image
- {
- QMutexLocker locker(&mutex);
- image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
- }
-
- for (unsigned x = 0; x < width; ++x) {
- if (cancelled) return;
- curX = x;
-
- // Get decoded samples from ffmpeg
- std::vector<float> data(step*2);
- mpeg.audioQueue(&*data.begin(), &*data.end(), x * step * 2);
-
- // Sample iterators for getting only one channel
- da::step_iterator<float> beginIt(&*data.begin(), 2);
- da::step_iterator<float> endIt(&*data.end(), 2);
-
- // Analyze
- if (cancelled) return;
- analyzer.input(beginIt, endIt);
- analyzer.process();
-
- // Peaks
- Analyzer::Peaks peaks = analyzer.getPeaks();
- for (unsigned i = 0; i < peaks.size(); ++i) {
- unsigned y = freq2px(peaks[i].freq);
- if (y == 0 || y >= height - 1) continue;
- float value = 0.003 * (level2dB(peaks[i].level) + 80.0);
- if (value <= 0.0) continue;
- Pixel p(0.0f, 0.0f, value);
- pixel(x, y) += p;
- p.r *= 0.5;
- p.g *= 0.5;
- p.b *= 0.5;
- pixel(x, y + 1) += p;
- pixel(x, y - 1) += p;
+ try {
+ unsigned int rate = 44100;
+ // Initialize FFmpeg decoding
+ FFmpeg mpeg(false, true, fileName.toStdString(), rate);
+ while(std::isnan(mpeg.duration())) msleep(1000); // Wait for ffmpeg to be ready
+ msleep(1000); // Wait some more
+
+ unsigned width = mpeg.duration() * rate / step;
+ img.resize(width * height);
+ Analyzer analyzer(rate, "");
+
+ QLabel *ngw = qobject_cast<QLabel*>(QWidget::parent());
+ if (ngw) {
+ ngw->setFixedSize(width, height);
+ } else return;
+
+ // Create image
+ {
+ QMutexLocker locker(&mutex);
+ image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
}
- // Tones
- Analyzer::Tones tones = analyzer.getTones();
- unsigned int i = 0;
- for (Analyzer::Tones::const_iterator it = tones.begin(), itend = tones.end(); it != itend && i < 3; ++it) {
- unsigned y = freq2px(it->freq);
- if (y == 0 || y >= height - 1) continue;
- float value = 0.003 * (level2dB(it->level) + 80.0);
- if (value <= 0.0) continue;
- Pixel p(0.0f, value, 0.0f);
- for (int j = int(y) - 2; j <= int(y) + 2; ++j) pixel(x, j) += p;
- }
+ for (unsigned x = 0; x < width; ++x) {
+ if (cancelled) return;
+ curX = x;
- // Draw
- {
+ // Get decoded samples from ffmpeg
+ std::vector<float> data(step*2);
+ if (!mpeg.audioQueue(&*data.begin(), &*data.end(), x * step * 2)) break;
+
+ // Sample iterators for getting only one channel
+ da::step_iterator<float> beginIt(&*data.begin(), 2);
+ da::step_iterator<float> endIt(&*data.end(), 2);
+
+ // Analyze
if (cancelled) return;
- QMutexLocker locker(&mutex);
- unsigned* rgba = reinterpret_cast<unsigned*>(image.bits());
- for (unsigned y = 0; y < height; ++y) {
- rgba[y * width + x] = pixel(x, y).rgba();
+ analyzer.input(beginIt, endIt);
+ analyzer.process();
+
+ // Peaks
+ Analyzer::Peaks peaks = analyzer.getPeaks();
+ for (unsigned i = 0; i < peaks.size(); ++i) {
+ unsigned y = freq2px(peaks[i].freq);
+ if (y == 0 || y >= height - 1) continue;
+ float value = 0.003 * (level2dB(peaks[i].level) + 80.0);
+ if (value <= 0.0) continue;
+ Pixel p(0.0f, 0.0f, value);
+ pixel(x, y) += p;
+ p.r *= 0.5;
+ p.g *= 0.5;
+ p.b *= 0.5;
+ pixel(x, y + 1) += p;
+ pixel(x, y - 1) += p;
+ }
+
+ // Tones
+ Analyzer::Tones tones = analyzer.getTones();
+ for (Analyzer::Tones::const_iterator it = tones.begin(), itend = tones.end(); it != itend; ++it) {
+ unsigned y = freq2px(it->freq);
+ if (y == 0 || y >= height - 1) continue;
+ float value = 0.003 * (level2dB(it->level) + 80.0);
+ if (value <= 0.0) continue;
+ Pixel p(0.0f, value, 0.0f);
+ for (int j = int(y) - 2; j <= int(y) + 2; ++j) pixel(x, j) += p;
+ }
+
+ // Draw
+ {
+ if (cancelled) return;
+ QMutexLocker locker(&mutex);
+ unsigned* rgba = reinterpret_cast<unsigned*>(image.bits());
+ for (unsigned y = 0; y < height; ++y) {
+ rgba[y * width + x] = pixel(x, y).rgba();
+ }
+ moreAvailable = true;
}
- moreAvailable = true;
}
+ } catch (std::exception& e) {
+ std::cerr << std::string("Error loading audio: ") + e.what() + '\n' << std::flush;
}
+ QMutexLocker locker(&mutex);
+ moreAvailable = true;
+ curX = width();
}
unsigned PitchVis::freq2px(double freq) const { return note2px(scale.getNote(freq)); }
diff --git a/pitchvis.hh b/pitchvis.hh
index 0af29c6..d38fb6e 100644
--- a/pitchvis.hh
+++ b/pitchvis.hh
@@ -42,8 +42,8 @@ class PitchVis: public QWidget, public QThread {
bool moreAvailable;
bool cancelled;
int curX;
- QMutex mutex;
public:
+ QMutex mutex;
const std::size_t height;
PitchVis(QString const& filename, QWidget *parent = NULL);
@@ -52,7 +52,7 @@ public:
void run(); // Thread runs here
void stop() { cancelled = true; }
- QImage getImage() { QMutexLocker locker(&mutex); moreAvailable = false; return image; }
+ QImage getImage() { moreAvailable = false; return image; }
bool newDataAvailable() const { return moreAvailable; }
int getXValue() const { return curX; }
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-21 14:36:08
|
Module: editor Branch: master Commit: 5c7339f9f193525c3c73ba5cab5044fbb0baab94 Author: Lasse Karkkainen <tro...@tr...> Date: Fri Jan 21 14:37:47 2011 +0100 Merge branch 'master' of git.performous.org:/gitroot/performous/editor --- |