浏览代码

new class BeatSequence

Fabian Peter Hammerle 10 年之前
父节点
当前提交
2cc1078d31
共有 8 个文件被更改,包括 199 次插入83 次删除
  1. 142 0
      BeatSequence.cpp
  2. 44 0
      BeatSequence.h
  3. 1 1
      ConfigurationScreen.cpp
  4. 8 13
      PlaybackScreen.cpp
  5. 1 1
      Sequencer.cpp
  6. 2 2
      Sequencer.h
  7. 0 65
      hardcopy.1
  8. 1 1
      midi

+ 142 - 0
BeatSequence.cpp

@@ -0,0 +1,142 @@
+#include "BeatSequence.h"
+
+void BeatSequenceNoteInformation::print(std::ostream& stream, std::size_t indent) const
+{
+    stream << std::string(indent, ' ') << "note on beat indices:";
+    for(BeatIndexMultiset::const_iterator it = onBeatIndices.begin(); it != onBeatIndices.end(); it++) {
+        stream << " " << *it;
+    }
+    stream << "\n";
+
+    stream << std::string(indent, ' ') << "note off beat indices:";
+    for(BeatIndexMultiset::const_iterator it = offBeatIndices.begin(); it != offBeatIndices.end(); it++) {
+        stream << " " << *it;
+    }
+    stream << "\n";
+
+    if(indent == 0) {
+        stream << "\n";
+    }
+    stream.flush();
+}
+
+void BeatSequenceNoteInformation::registerMessage(BeatSequence::BeatIndex beatIndex, const std::shared_ptr<midi::NoteMessage>& noteMsg_ptr)
+{
+    if(std::dynamic_pointer_cast<midi::NoteOnMessage>(noteMsg_ptr)) {
+        onBeatIndices.insert(beatIndex);
+    } else {
+        offBeatIndices.insert(beatIndex);
+    }
+}
+
+void BeatSequenceNoteInformation::unregisterMessage(BeatSequence::BeatIndex beatIndex, const std::shared_ptr<midi::NoteMessage>& noteMsg_ptr)
+{
+    BeatIndexMultiset::const_iterator it;
+    if(std::dynamic_pointer_cast<midi::NoteOnMessage>(noteMsg_ptr)) {
+        it = onBeatIndices.find(beatIndex);
+        if(it != onBeatIndices.end()) {
+            onBeatIndices.erase(it);
+        }
+    } else {
+        it = offBeatIndices.find(beatIndex);
+        if(it != offBeatIndices.end()) {
+            offBeatIndices.erase(it);
+        }
+    }
+}
+
+const midi::MessageList& BeatSequence::at(BeatIndex beatIndex) const
+{
+    return parent::at(beatIndex);
+}
+
+const midi::MessageList& BeatSequence::operator[](BeatIndex beatIndex) const
+{
+    return parent::operator[](beatIndex);
+}
+
+void BeatSequence::resize(BeatIndex size)
+{
+    parent::resize(size);
+    refreshRegistry();
+}
+
+void BeatSequence::pushBackMessage(BeatIndex beatIndex, std::shared_ptr<midi::Message>& msg_ptr)
+{
+    parent::at(beatIndex).push_back(msg_ptr);
+    registerMessage(beatIndex, msg_ptr);
+}
+
+void BeatSequence::eraseMessage(BeatIndex beatIndex, midi::MessageList::const_iterator msg_it)
+{
+    unregisterMessage(beatIndex, *msg_it);
+    parent::at(beatIndex).erase(msg_it);
+}
+
+void BeatSequence::expand(BeatIndex factor)
+{
+    parent::expand(factor);
+    refreshRegistry();
+}
+
+void BeatSequence::reduceToNeighbour(BeatIndex factor)
+{
+    parent::reduceToNeighbour(factor);
+    refreshRegistry();
+}
+
+void BeatSequence::reduceErasingConflicts(BeatIndex factor)
+{
+    parent::reduceErasingConflicts(factor);
+    refreshRegistry();
+}
+
+void BeatSequence::printRegistry(std::ostream& stream) const
+{
+    stream << "beat sequence note info registry: \n";
+    for(NoteInfoMap::const_iterator noteInfo_it = noteInfos.begin(); noteInfo_it != noteInfos.end(); noteInfo_it++) {
+        stream << std::string(4, ' ');
+        stream << "channel #" << (int)(noteInfo_it->first.first + 1);
+        stream << " pitch=" << (int)noteInfo_it->first.second << ": \n";
+        noteInfo_it->second.print(stream, 8); 
+    }
+    stream.flush();
+}
+
+BeatSequenceNoteInformation& BeatSequence::getNoteInfo(Channel channel, Pitch pitch)
+{
+    ChannelPitchPair key(channel, pitch);
+    return noteInfos[key];
+}
+
+void BeatSequence::refreshRegistry()
+{
+    noteInfos.clear();
+
+    for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
+        const midi::MessageList& beat = at(beatIndex);
+        for(midi::MessageList::const_iterator msg_it = beat.begin(); msg_it != beat.end(); msg_it++) {
+            registerMessage(beatIndex, *msg_it);
+        }
+    }
+}
+
+void BeatSequence::registerMessage(BeatIndex beatIndex, const std::shared_ptr<midi::Message>& msg_ptr)
+{
+    std::shared_ptr<midi::NoteMessage> noteMsg_ptr
+        = std::dynamic_pointer_cast<midi::NoteMessage>(msg_ptr);
+    if(noteMsg_ptr) {
+        getNoteInfo(noteMsg_ptr->channel, noteMsg_ptr->pitch)
+            .registerMessage(beatIndex, noteMsg_ptr);
+    }
+}
+
+void BeatSequence::unregisterMessage(BeatIndex beatIndex, const std::shared_ptr<midi::Message>& msg_ptr)
+{
+    std::shared_ptr<midi::NoteMessage> noteMsg_ptr
+        = std::dynamic_pointer_cast<midi::NoteMessage>(msg_ptr);
+    if(noteMsg_ptr) {
+        getNoteInfo(noteMsg_ptr->channel, noteMsg_ptr->pitch)
+            .unregisterMessage(beatIndex, noteMsg_ptr);
+    }
+}

+ 44 - 0
BeatSequence.h

@@ -0,0 +1,44 @@
+#include "midi/BeatSequence.h"
+#include <set>
+#include <map>
+#include <ostream>
+
+class BeatSequenceNoteInformation
+{
+    typedef std::multiset<midi::BeatSequence::BeatIndex> BeatIndexMultiset;
+public:
+    BeatIndexMultiset onBeatIndices, offBeatIndices;
+
+	void print(std::ostream& stream, std::size_t indent = 0) const;
+    void registerMessage(midi::BeatSequence::BeatIndex beatIndex, const std::shared_ptr<midi::NoteMessage>& noteMsg_ptr);
+    void unregisterMessage(midi::BeatSequence::BeatIndex beatIndex, const std::shared_ptr<midi::NoteMessage>& noteMsg_ptr);
+};
+
+class BeatSequence : public midi::BeatSequence
+{
+    typedef midi::BeatSequence parent;
+
+    typedef midi::ChannelMessage::Channel Channel;
+    typedef midi::NoteMessage::Pitch Pitch;
+    typedef std::pair<Channel, Pitch> ChannelPitchPair;
+    typedef std::map<ChannelPitchPair, BeatSequenceNoteInformation> NoteInfoMap;
+
+    NoteInfoMap noteInfos;
+
+public:
+    const midi::MessageList& at(BeatIndex beatIndex) const;
+    const midi::MessageList& operator[](BeatIndex beatIndex) const;
+    void resize(BeatIndex size);
+    void pushBackMessage(BeatIndex beatIndex, std::shared_ptr<midi::Message>& msg_ptr);
+    void eraseMessage(BeatIndex beatIndex, midi::MessageList::const_iterator msg_it);
+    void expand(BeatIndex factor);
+    void reduceToNeighbour(BeatIndex factor);
+    void reduceErasingConflicts(BeatIndex factor);
+    void printRegistry(std::ostream& stream) const;
+
+private:
+    BeatSequenceNoteInformation& getNoteInfo(Channel channel, Pitch pitch);
+    void refreshRegistry();
+    void registerMessage(BeatIndex beatIndex, const std::shared_ptr<midi::Message>& msg_ptr);
+    void unregisterMessage(BeatIndex beatIndex, const std::shared_ptr<midi::Message>& msg_ptr);
+};

+ 1 - 1
ConfigurationScreen.cpp

@@ -43,7 +43,7 @@ void ConfigurationScreen::keyPressed(unsigned char x, unsigned char y)
                     ));
                 } break;
         }
-        sequencer.beats.print(std::cout);
+        // sequencer.beats.print(std::cout);
     }
 
     refreshAll();

+ 8 - 13
PlaybackScreen.cpp

@@ -24,7 +24,7 @@ void PlaybackScreen::enable()
 
 void PlaybackScreen::beforeBeat(Player::BeatIndex beat)
 {
-    std::cout << "before beat #" << beat << std::endl;
+    // std::cout << "before beat #" << beat << std::endl;
     beatDisplayOffset = beat / beatDisplayWidth * beatDisplayWidth;
     refreshAll();
 }
@@ -35,7 +35,7 @@ void PlaybackScreen::afterBeat(Player::BeatIndex beat)
 
 void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
 {
-    std::cout << "clicked x=" << (int)x << ", y=" << (int)y << std::endl;
+    // std::cout << "clicked x=" << (int)x << ", y=" << (int)y << std::endl;
 
     if(x == 8) { // very right
         if(y < sequencer.messages.size()) {
@@ -71,23 +71,18 @@ void PlaybackScreen::keyPressed(unsigned char x, unsigned char y)
     } else {
         Player::BeatIndex beatIndex = x + beatDisplayOffset;
         if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
-            midi::MessageList& beat = sequencer.beats[beatIndex];
-            std::cout << "before ";
-            beat.print(std::cout);
-
+            const midi::MessageList& beat = sequencer.beats[beatIndex];
             std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[y];
-            msg_ptr->print(std::cout);
+            // msg_ptr->print(std::cout);
             midi::MessageList::const_iterator beat_msg_it = beat.find(*msg_ptr);
             if(beat_msg_it == beat.end()) {
                 // insert message at beat
-                beat.push_back(msg_ptr);
+                sequencer.beats.pushBackMessage(beatIndex, msg_ptr);
             } else {
                 // remove message from beat
-                beat.erase(beat_msg_it);
+                sequencer.beats.eraseMessage(beatIndex, beat_msg_it);
             }
-
-            std::cout << "after ";
-            beat.print(std::cout);
+            sequencer.beats.printRegistry(std::cout);
         }
     }
 
@@ -138,7 +133,7 @@ void PlaybackScreen::refresh(unsigned char x, unsigned char y)
     } else {
         Player::BeatIndex beatIndex = x + beatDisplayOffset;
         if(beatIndex < sequencer.beats.size() && y < sequencer.messages.size()) {
-            midi::MessageList& beat = sequencer.beats[beatIndex];
+            const midi::MessageList& beat = sequencer.beats[beatIndex];
             std::shared_ptr<midi::Message> msg_ptr = sequencer.messages[y];
             if(beat.contains(*msg_ptr)) {
                 if(sequencer.player.getNextBeat() == beatIndex) {

+ 1 - 1
Sequencer.cpp

@@ -25,7 +25,7 @@ void Sequencer::run()
 
     playbackScreen.enable();
 
-    player.setBpm(320);
+    player.setBpm(256);
 
     std::cin.ignore();
 }

+ 2 - 2
Sequencer.h

@@ -3,7 +3,7 @@
 #include <memory>
 #include "midi/Launchpad.h"
 #include "midi/Message.h"
-#include "midi/BeatSequence.h"
+#include "BeatSequence.h"
 #include "PlaybackScreen.h"
 #include "ConfigurationScreen.h"
 #include "Player.h"
@@ -17,7 +17,7 @@ public:
     std::vector<std::shared_ptr<midi::Message>> messages;
     unsigned char defaultOutputChannel;
     midi::Output midiOut;
-    midi::BeatSequence beats;
+    BeatSequence beats;
     Player player;
 
     Sequencer();

+ 0 - 65
hardcopy.1

@@ -1,65 +0,0 @@
-path: /home/fabianpeter/.scripts:/home/fabianpeter/.scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/b
-in:/usr/games:/usr/local/games
-python path: :/home/fabianpeter/.scripts/lib:/home/fabianpeter/.scripts/lib
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $ ;s
-bash: syntax error near unexpected token `;'
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $ ls
-bin    CMakeLists.txt  ConfigurationScreen.cpp  main.cpp  PlaybackScreen.cpp  Player.cpp  Screen.cpp  Sequencer.cpp
-build  colors.h        ConfigurationScreen.h    midi      PlaybackScreen.h    Player.h    Screen.h    Sequencer.h
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $ cd midi
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer/midi $ ./build
--- Configuring done
--- Generating done
--- Build files have been written to: /home/fabianpeter/projects/informatics/applications/launchpad-sequencer/midi/lib
-[100%] Built target midi
--- Configuring done
--- Generating done
--- Build files have been written to: /home/fabianpeter/projects/informatics/applications/launchpad-sequencer/midi/test
-s/bin
-[ 10%] Built target beat-sequence-expansion
-[ 20%] Built target beat-sequence-player
-[ 30%] Built target beat-sequence-reducation
-[ 40%] Built target callback-clock
-[ 50%] Built target clock
-[ 60%] Built target launchpad
-[ 70%] Built target launchpad-screen
-[ 80%] Built target message-comparison
-[ 90%] Built target message-list-find
-[100%] Built target midiout
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer/midi $ cd ..
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $ ls
-bin    CMakeLists.txt  ConfigurationScreen.cpp  main.cpp  PlaybackScreen.cpp  Player.cpp  Screen.cpp  Sequencer.cpp
-build  colors.h        ConfigurationScreen.h    midi      PlaybackScreen.h    Player.h    Screen.h    Sequencer.h
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $ ls
-bin    CMakeLists.txt  ConfigurationScreen.cpp  main.cpp  PlaybackScreen.cpp  Player.cpp  Screen.cpp  Sequencer.cpp
-build  colors.h        ConfigurationScreen.h    midi      PlaybackScreen.h    Player.h    Screen.h    Sequencer.h
-fabianpeter@arma-nova ~/projects/informatics/applications/launchpad-sequencer $
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+ 1 - 1
midi

@@ -1 +1 @@
-Subproject commit 377f02d6f9189f8a6e5f911ea9dbfe7fb62c1911
+Subproject commit defc63e484af3a00b0cee9087280b3f455fc92e1