git-svn-id: https://svn.code.sf.net/p/pianobooster/code/trunk@31 ba081f5d-443b-49a7-ac4b-446c3f91f371

This commit is contained in:
louisjb 2009-03-05 21:11:11 +00:00
parent aa7b3b153f
commit 684d814571
20 changed files with 158 additions and 81 deletions

View File

@ -86,6 +86,11 @@ ADD_DEFINITIONS( -Wall)
# other modules must be enabled like this:
SET(QT_USE_QTOPENGL TRUE)
FIND_PACKAGE( OpenGL REQUIRED )
MESSAGE("the GL include directory ${OPENGL_INCLUDE_DIR}")
# this command finds Qt4 libraries and sets all required variables
# note that it's Qt4, not QT4 or qt4
FIND_PACKAGE( Qt4 REQUIRED )
@ -106,7 +111,7 @@ QT4_WRAP_CPP( PIANOBOOSTER_MOC_SRCS ${PIANOBOOSTER_MOC_HDRS} )
# we need this to be able to include headers produced by uic in our code
# (CMAKE_BINARY_DIR holds a path to the build directory, while INCLUDE_DIRECTORIES() works just like INCLUDEPATH from qmake)
INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} )
INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ${OPENGL_INCLUDE_DIR})
# here we instruct CMake to build "pianobooster" executable from all of the source files
ADD_EXECUTABLE( pianobooster ${PIANOBOOSTER_SRCS} ${PIANOBOOSTER_MOC_SRCS}

View File

@ -70,7 +70,7 @@ public:
static const float staveThickness() {return 1;}
static const int playZoneEarly() {return m_playZoneEarly;} // 20 Was 25
static const int playZoneEarly() {return m_playZoneEarly;}
static const int playZoneLate() {return m_playZoneLate;}
static const int silenceTimeOut() {return 8000;} // the time in msec before everything goes quiet
static const int chordNoteGap() {return 10;} // all notes in a cord must be spaced less than this a gap

View File

@ -64,6 +64,7 @@ CConductor::CConductor()
m_realTimeEventBits = 0;
m_mutePianistPart = false;
setPianistChannels(1-1,2-1);
cfg_timingMarkersFlag = false;
for ( i = 0; i < MAX_MIDI_CHANNELS; i++)
{
@ -197,6 +198,11 @@ int CConductor::calcBoostVolume(int channel, int volume)
if (channel == m_activeChannel)
activePart= true;
}
if (channel == m_activeChannel)
activePart= true;
//if (channel == 5) activePart= true; // for debuging
if (activePart)
{
if (returnVolume == 0 )
@ -350,6 +356,11 @@ void CConductor::playMusic(bool start)
activatePianistMutePart();
testWrongNoteSound(false);
if (seekingBarNumber())
resetWantedChord();
ppTrace("setLatencyFix %d", getLatencyFix()); // Fixme
@ -408,14 +419,32 @@ void CConductor::resetWantedChord()
m_wantedChord.clear();
ppDEBUG_CONDUCTOR(("resetWantedChord m_chordDeltaTime %d m_playingDeltaTime %d", m_chordDeltaTime, m_playingDeltaTime ));
m_followPlayingTimeOut = false;
m_chordDeltaTime = m_playingDeltaTime;
m_pianistTiming = m_chordDeltaTime;
m_pianistSplitPoint = MIDDLE_C;
m_followPlayingTimeOut = CMidiFile::ppqnAdjust(Cfg::playZoneLate() * SPEED_ADJUST_FACTOR);
outputSavedNotes();
m_followState = PB_FOLLOW_searching;
}
// switch modes if we are playing well enough (ie don't slow down if we are playing late)
void CConductor::setFollowSkillAdvanced(bool enable)
{
if (getLatencyFix() == 0)
{
m_followSkillAdvanced = enable;
m_stopPoint = (enable) ? m_cfg_stopPointAdvanced: m_cfg_stopPointBeginner ;
}
else
{
// behave differently if we are using the latency fix
m_cfg_earlyNotesPoint = m_cfg_imminentNotesOffPoint; //disable the earily notes
m_followSkillAdvanced = true;
}
}
void CConductor::findSplitPoint()
{
// find the split point
@ -440,7 +469,7 @@ void CConductor::findSplitPoint()
void CConductor::fetchNextChord()
{
m_followState = PB_FOLLOW_searching;
m_followPlayingTimeOut = m_cfg_playZoneLate;
m_followPlayingTimeOut = false;
outputSavedNotes();
@ -455,6 +484,7 @@ void CConductor::fetchNextChord()
m_wantedChord = m_wantedChordQueue->pop();
m_savedwantedChord = m_wantedChord;
m_chordDeltaTime -= m_wantedChord.getDeltaTime() * SPEED_ADJUST_FACTOR;
m_pianistTiming = m_chordDeltaTime;
}
while (m_wantedChord.trimOutOfRangeNotes(m_transpose)==0);
@ -506,10 +536,10 @@ void CConductor::pianistInput(CMidiEvent inputNote)
{
m_goodPlayedNotes.addNote(hand, inputNote.note());
m_goodNoteLines.addNote(hand, inputNote.note());
int pianistTiming = m_chordDeltaTime + m_cfg_playZoneLate - m_followPlayingTimeOut;
int pianistTiming = (/*m_followPlayingTimeOut ||*/ !cfg_timingMarkersFlag) ? NOT_USED : m_pianistTiming;
m_scoreWin->setPlayedNoteColour(inputNote.note(),
(m_followPlayingTimeOut)? Cfg::playedGoodColour():Cfg::playedBadColour(),
m_chordDeltaTime);//pianistTiming);
(!m_followPlayingTimeOut)? Cfg::playedGoodColour():Cfg::playedBadColour(),
m_chordDeltaTime, pianistTiming);
if (validatePianistChord() == true)
@ -517,14 +547,14 @@ void CConductor::pianistInput(CMidiEvent inputNote)
if (m_chordDeltaTime < 0)
m_tempo.removePlayingTicks(-m_chordDeltaTime);
ppLogWarn ("notes %d, time %d %3d %3d", m_goodPlayedNotes.length(), deltaAdjust(pianistTiming),
deltaAdjust(-m_chordDeltaTime),
deltaAdjust( m_cfg_playZoneLate - m_followPlayingTimeOut ) );//fixme
m_goodPlayedNotes.clear();
fetchNextChord();
// count the good notes so that the live percentage looks OK
m_rating.totalNotes(m_wantedChord.length());
if (m_rating.getAccuracyValue() > 0.8)
setFollowSkillAdvanced(true); // change the skill level only when they are good enough
else
setFollowSkillAdvanced(false);
setEventBits( EVENT_BITS_forceRatingRedraw);
}
}
@ -550,7 +580,7 @@ void CConductor::pianistInput(CMidiEvent inputNote)
if (hasNote)
m_scoreWin->setPlayedNoteColour(inputNote.note(),
(m_followPlayingTimeOut)? Cfg::noteColour():Cfg::playedStoppedColour(),
(!m_followPlayingTimeOut)? Cfg::noteColour():Cfg::playedStoppedColour(),
m_chordDeltaTime);
outputSavedNotesOff();
@ -608,24 +638,25 @@ void CConductor::followPlaying()
if (m_wantedChord.length() == 0)
return;
/* fixme delete
if (deltaAdjust(m_chordDeltaTime) > -m_cfg_earlyNotesPoint && !seekingBarNumber() )
m_followState = PB_FOLLOW_earlyNotes;
/*/
if (seekingBarNumber())
{
if (deltaAdjust(m_chordDeltaTime) > -m_cfg_stopPoint )
if (deltaAdjust(m_chordDeltaTime) > -m_stopPoint )
fetchNextChord();
}
else if ( m_playMode == PB_PLAY_MODE_followYou)
{
if (deltaAdjust(m_chordDeltaTime) > -m_cfg_earlyNotesPoint )
m_followState = PB_FOLLOW_earlyNotes;
if (deltaAdjust(m_chordDeltaTime) > -m_cfg_stopPoint )
if (deltaAdjust(m_chordDeltaTime) > -m_stopPoint )
{
m_followState = PB_FOLLOW_waiting;
// Throw away the time past the stop point (by adding a negative ticks)
addDeltaTime( m_cfg_stopPoint*SPEED_ADJUST_FACTOR - m_chordDeltaTime);
addDeltaTime( -m_stopPoint*SPEED_ADJUST_FACTOR - m_chordDeltaTime);
}
}
else // m_playMode == PB_PLAY_MODE_playAlong
@ -689,6 +720,9 @@ void CConductor::realTimeEngine(int mSecTicks)
ticks = m_tempo.mSecToTicks(mSecTicks);
if (!m_followPlayingTimeOut)
m_pianistTiming += ticks;
while (checkMidiInput() > 0)
pianistInput(readMidiInput());
@ -705,15 +739,15 @@ void CConductor::realTimeEngine(int mSecTicks)
}
if (m_followPlayingTimeOut > 0)
if (m_pianistTiming > m_cfg_playZoneLate)
{
m_tempo.insertPlayingTicks(ticks);
m_followPlayingTimeOut -= ticks;
if (m_followPlayingTimeOut <= 0)
if (m_followPlayingTimeOut == false)
{
m_followPlayingTimeOut = true;
m_tempo.clearPlayingTicks();
m_followPlayingTimeOut = 0;
m_rating.lateNotes(m_wantedChord.length() - m_goodPlayedNotes.length());
setEventBits( EVENT_BITS_forceRatingRedraw);
@ -747,7 +781,7 @@ void CConductor::realTimeEngine(int mSecTicks)
{
ppDEBUG_CONDUCTOR(("m_savedNoteQueue %d m_playingDeltaTime %d",m_savedNoteQueue->space() , m_playingDeltaTime ));
ppDEBUG_CONDUCTOR(("getfollowState() %d %d %d",getfollowState() , m_leadLagAdjust, m_songEventQueue->length() ));
//fixme setEventBits( EVENT_BITS_forceBarNumberRedraw);
//fixme this did not work setEventBits( EVENT_BITS_forceBarNumberRedraw);
setEventBits( EVENT_BITS_forceFullRedraw);
}
@ -785,7 +819,10 @@ void CConductor::realTimeEngine(int mSecTicks)
//if (isChannelMuted(channel) == false) //fixme
if (channel!= m_pianistGoodChan && channel!= m_pianistBadChan)
{
if (getfollowState() >= PB_FOLLOW_earlyNotes && m_playMode == PB_PLAY_MODE_followYou && !seekingBarNumber())
if (getfollowState() >= PB_FOLLOW_earlyNotes &&
m_playMode == PB_PLAY_MODE_followYou &&
!seekingBarNumber() &&
m_followSkillAdvanced == false)
{
// Save up the notes until the pianist press the right key
if (m_savedNoteQueue->space()>0)
@ -847,13 +884,14 @@ void CConductor::rewind()
m_badNoteLines.clear();
resetWantedChord();
m_cfg_earlyNotesPoint = CMidiFile::ppqnAdjust(20); // was 10 playZoneEarly
m_cfg_stopPoint = CMidiFile::ppqnAdjust(0); //was -3; // stop just after the beat
m_cfg_earlyNotesPoint = CMidiFile::ppqnAdjust(15); // was 10 playZoneEarly
m_cfg_stopPointBeginner = CMidiFile::ppqnAdjust(-0); //was -3; // stop just after the beat
m_cfg_stopPointAdvanced = CMidiFile::ppqnAdjust(-15); //was -3; // stop just after the beat
m_cfg_imminentNotesOffPoint = CMidiFile::ppqnAdjust(-15); // look ahead and find an Notes off coming up
// Annie song 25
if (getLatencyFix()!=0)
m_cfg_imminentNotesOffPoint = 0;
setFollowSkillAdvanced(false);
// Annie song 25
m_cfg_playZoneEarly = CMidiFile::ppqnAdjust(Cfg::playZoneEarly()) * SPEED_ADJUST_FACTOR; // when playing along
m_cfg_playZoneLate = CMidiFile::ppqnAdjust(Cfg::playZoneLate()) * SPEED_ADJUST_FACTOR;

View File

@ -185,6 +185,8 @@ public:
void setPlayFromBar(double bar){ m_bar.setPlayFromBar(bar);}
void mutePianistPart(bool state);
bool cfg_timingMarkersFlag;
protected:
CScore* m_scoreWin;
@ -253,7 +255,7 @@ private:
return true;
return m_muteChannels[chan];
}
void setFollowSkillAdvanced(bool enable);
CTempo m_tempo;
CBar m_bar;
@ -265,18 +267,23 @@ private:
CChord m_goodNoteLines; // The coloured note lines that appear on the score when the pianist plays
CChord m_badNoteLines;
int m_pianistSplitPoint; // Defines which notes go in the base and treble clef
bool m_followSkillAdvanced;
int m_lastSound;
int m_stopPoint; // Were we stop the music if the pianist is late
int m_cfg_rightNoteSound;
int m_cfg_wrongNoteSound;
int m_pianistGoodChan;
int m_pianistBadChan;
int m_cfg_earlyNotesPoint; // don't press the note too early
int m_cfg_stopPoint; // Were we stop the music if the pianist is late
int m_followPlayingTimeOut; // O dear, the student is too slow
int m_cfg_stopPointAdvanced; // Were we stop the music if the pianist is late
int m_cfg_stopPointBeginner; // Were we stop the music if the pianist is late
int m_cfg_imminentNotesOffPoint;
int m_cfg_playZoneEarly; // when playing along
int m_cfg_playZoneLate;
int m_pianistTiming; //measure whether the pianest is playing early or late
bool m_followPlayingTimeOut; // O dear, the student is too slow
bool m_testWrongNoteSound;
int m_boostVolume;
int m_pianoVolume;

View File

@ -455,7 +455,7 @@ void CDraw::drawSymbol(CSymbol symbol, float x, float y)
int pianistX = symbol.getPianistTiming();
if ( pianistX != NOT_USED)
{
pianistX = x - pianistX * HORIZONTAL_SPACING_FACTOR;
pianistX = x + pianistX * HORIZONTAL_SPACING_FACTOR;
drColour(CColour(1.0, 1.0, 1.0));
glLineWidth (2.0);
glBegin(GL_LINES);

View File

@ -36,9 +36,6 @@
#include "Cfg.h"
#include "Draw.h"
int nextListId; //fixme
CGLView::CGLView(Window *parent)
: QGLWidget(parent)
{
@ -55,7 +52,7 @@ CGLView::CGLView(Window *parent)
m_score = new CScore();
m_midiTicks = 0;
m_scrollTicks = 0;
m_cfg_openGlOptimise = false;
m_cfg_openGlOptimise = false;
}
CGLView::~CGLView()
@ -64,11 +61,6 @@ CGLView::~CGLView()
delete m_song;
delete m_score;
m_titleHeight = 0;
if (nextListId)
{
glDeleteLists(nextListId, 1);
nextListId = 0;
}
}
@ -166,7 +158,10 @@ void CGLView::drawAccurracyBar()
const int width = 360;
const int lineWidth = 8/2;
m_rating->getAccuracy(&colour, &accuracy);
m_rating->calculateAccuracy();
accuracy = m_rating->getAccuracyValue();
colour = m_rating->getAccuracyColour();
CDraw::drColour (colour);
glRectf(x, y - lineWidth, x + width * accuracy, y + lineWidth);
CDraw::drColour (Cfg::backgroundColour());
@ -320,15 +315,7 @@ void CGLView::init()
m_song->setActiveHand(PB_PART_both);
if (!Cfg::quickStart)
renderText(10,10,"x",m_timeRatingFont); //fixme
/*
nextListId = glGenLists (1);
glNewList (nextListId, GL_COMPILE);
//renderText(10.0,10.0,0.0,"xxxxx");
//renderText(10,10,"xxxxx");
glEndList ();
// */
renderText(10,10,"~", m_timeRatingFont); //fixme this is a work arround for a QT bug.
setFocusPolicy(Qt::ClickFocus);

View File

@ -118,15 +118,15 @@ void GuiMidiSetupDialog::updateMidiInfoText()
void GuiMidiSetupDialog::on_midiInputCombo_activated (int index)
{
updateMidiInfoText();
m_midiChanged = true;
updateMidiInfoText();
}
void GuiMidiSetupDialog::on_midiOutputCombo_activated (int index)
{
updateMidiInfoText();
m_midiChanged = true;
m_latencyFix = 0;
m_midiChanged = true;
updateMidiInfoText();
}
void GuiMidiSetupDialog::on_latencyFixButton_clicked ( bool checked )
@ -152,8 +152,8 @@ void GuiMidiSetupDialog::on_latencyFixButton_clicked ( bool checked )
if (ok)
{
m_latencyFix = latencyFix;
updateMidiInfoText();
m_latencyChanged = true;
updateMidiInfoText();
}
}

View File

@ -44,18 +44,19 @@ void GuiPreferencesDialog::init(CSong* song, QSettings* settings, CGLView * glVi
m_song = song;
m_settings = settings;
m_glView = glView;
displayOptimiseCheck->setChecked(m_glView->m_cfg_openGlOptimise);
}
void GuiPreferencesDialog::on_displayOptimiseCheck_toggled(bool checked)
{
videoOptimiseCheck->setChecked(m_glView->m_cfg_openGlOptimise);
timingMarkersCheck->setChecked(m_song->cfg_timingMarkersFlag);
}
void GuiPreferencesDialog::accept()
{
m_glView->m_cfg_openGlOptimise = displayOptimiseCheck->isChecked();
m_settings->setValue("display/openGlOptimise", m_glView->m_cfg_openGlOptimise );
this->QDialog::accept();
m_glView->m_cfg_openGlOptimise = videoOptimiseCheck->isChecked();
m_settings->setValue("display/openGlOptimise", m_glView->m_cfg_openGlOptimise );
//void on_timingMarkersCheck_toggled (bool checked);
m_song->cfg_timingMarkersFlag = timingMarkersCheck->isChecked();
m_settings->setValue("score/timingMarkers", m_song->cfg_timingMarkersFlag );
this->QDialog::accept();
}

View File

@ -45,11 +45,10 @@ class GuiPreferencesDialog : public QDialog, private Ui::GuiPreferencesDialog
public:
GuiPreferencesDialog(QWidget *parent = 0);
void init(CSong* song, QSettings* settings, CGLView* glView);
void init(CSong* song, QSettings* settings, CGLView* glView);
private slots:
void accept();
void on_displayOptimiseCheck_toggled (bool checked);
private:
QSettings* m_settings;

View File

@ -13,16 +13,38 @@
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="QGroupBox" name="groupBox_2" >
<property name="title" >
<string>Score Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" >
<item>
<widget class="QCheckBox" name="timingMarkersCheck" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Timing markers</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Display Settings</string>
<string>Video Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QCheckBox" name="displayOptimiseCheck" >
<widget class="QCheckBox" name="videoOptimiseCheck" >
<property name="text" >
<string>Enable display optimisation</string>
<string>Video optimisation</string>
</property>
</widget>
</item>

View File

@ -222,5 +222,4 @@ void GuiTopBar::on_saveBarButton_clicked(bool clicked)
startBarSpin->setValue(barNumber);
//on_startBarSpin_valueChanged(barNumber);
//m_song->setPlayFromBar( barNumber); fixme
}

View File

@ -179,6 +179,8 @@ void CMidiDevice::playMidiEvent(CMidiEvent event)
}
m_midiout->sendMessage( &message );
//event.printDetails(); // usefull for debuging
}

View File

@ -220,6 +220,10 @@ public:
m_velocity = 0;
}
void printDetails()
{
ppTiming("chan %2d type %2X note %3d", channel(), type(), note() );
}
private:
int m_type;

View File

@ -107,8 +107,7 @@ Window::Window()
#endif
m_glWidget->m_cfg_openGlOptimise = m_settings->value("display/openGlOptimise", m_glWidget->m_cfg_openGlOptimise ).toBool();
m_song->cfg_timingMarkersFlag = m_settings->value("score/timingMarkers", m_song->cfg_timingMarkersFlag ).toBool();
m_song->openMidiPort(0, string(midiInputName.toAscii()));

View File

@ -40,7 +40,7 @@ void CRating::reset()
m_factor = 2.0;
}
bool CRating::getAccuracy(CColour* colourPtr, float* accuracyPtr)
void CRating::calculateAccuracy()
{
int direction = 0;
@ -99,11 +99,6 @@ bool CRating::getAccuracy(CColour* colourPtr, float* accuracyPtr)
}
}
}
*colourPtr = m_currentColour;
*accuracyPtr = m_currentAccuracy;
return (direction == 0)? false : true;
}

View File

@ -56,7 +56,10 @@ public:
return percent;
}
bool getAccuracy(CColour* colourPtr, float* accuracyPtr);
void calculateAccuracy();
float getAccuracyValue(){ return m_currentAccuracy; }
CColour getAccuracyColour() { return m_currentColour; }
private:
int m_totalNotesCount;

View File

@ -314,5 +314,5 @@ void CScroll::reset()
m_scrollQueue->clear();
m_ppqnFactor = static_cast<float>(DEFAULT_PPQN) / CMidiFile::getPulsesPerQuarterNote();
m_noteSpacingFactor = m_ppqnFactor * 0.75; //HORIZONTAL_SPACING_FACTOR // fixme
m_noteSpacingFactor = m_ppqnFactor * HORIZONTAL_SPACING_FACTOR;
}

View File

@ -115,7 +115,7 @@ public:
{
if (m_symbolType == PB_SYMBOL_note)
m_midiNote += amount;
m_stavePos.notePos(m_hand, m_midiNote); // fixme remove m_stavePos
m_stavePos.notePos(m_hand, m_midiNote); // The save possition has now moved
}
private:

View File

@ -33,8 +33,12 @@
#include <sstream>
#include "Util.h"
#include "Cfg.h"
#include <QTime>
static QTime s_realtime;
/* prints an error message to stderr, and dies */
void fatal(const char *msg, ...)
{
@ -95,6 +99,7 @@ void ppTrace(const char *msg, ...)
fputc('\n', stdout);
}
void ppDebug( const char *msg, ...)
{
va_list ap;
@ -116,3 +121,13 @@ void ppError(const char *msg, ...)
fputc('\n', stdout);
}
void ppTiming(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
fprintf(stdout, "T %4d " , s_realtime.restart() );
vfprintf(stdout, msg, ap);
va_end(ap);
fputc('\n', stdout);
}

View File

@ -64,6 +64,7 @@ void ppError(const char *msg, ...);
void ppLog(logLevel_t level, const char *msg, ...);
void ppLogInfo(const char *msg, ...);
void ppLogWarn(const char *msg, ...);
void ppTiming(const char *msg, ...);
#define SPEED_ADJUST_FACTOR 1000
#define deltaAdjust(delta) ((delta)/SPEED_ADJUST_FACTOR )