2015-06-05 18 views
-1

我正在嘗試在C++中創建一個步序列器,它最終會發出MIDI數據。我通過在自己的線程上有一個時鐘來計算自上一次拍子以來的時間量,並且如果是下一次拍子的時間,它會將一段數據寫入控制檯。如何在自己的線程上運行時鐘

但是,我發現無論我將BPM設置爲什麼,我都會以顯着太慢的速度收到消息。我似乎無法弄清楚爲什麼在這個線程上的時間是錯誤的,並且這對我並不熟悉庫如何工作非常熟悉。思考?下面

代碼:

#include <thread> 
#include <mutex> 
#include <chrono> 
#include <vector> 
#include <iostream> 

class StepSequencer { 
public: 
    StepSequencer(); 
    ~StepSequencer(); 
    void run(); 
    void setBeatsPerMinute(float bpm); 
    void addNote(int noteValue, int beatIndex); 
    void playNote(int beatIndex); 
protected: 
    int mNumberOfBeatBins; 
    int mSequencerPlayhead; 
    float mBeatsPerMinute; 
    float mSecondsPerBeat; 
    std::vector<int> mBeatBins; 
    std::mutex mMutex; 
    std::thread mSequencerThread; 
    bool mRunSequencerThread; 
    std::chrono::time_point<std::chrono::system_clock> mLastBeatTime; 
    std::chrono::time_point<std::chrono::system_clock> mCurrentTime; 
}; 

#include "stdafx.h" 
#include "StepSequencer.h" 

StepSequencer::StepSequencer() { 
    mNumberOfBeatBins = 16; 
    for(int i = 0; i < 16; i++) { 
    mBeatBins.push_back(0); 
    } 

    mBeatsPerMinute = 0; 
    mSecondsPerBeat = 1; 

    mLastBeatTime = std::chrono::system_clock::now(); 
    mCurrentTime = std::chrono::system_clock::now(); 

    mSequencerPlayhead = 0; 

    mRunSequencerThread = false; 
    mSequencerThread = std::thread(&StepSequencer::run, this); 
} 

StepSequencer::~StepSequencer() { 
    if(mSequencerThread.joinable()) { 
    mSequencerThread.join(); 
    } 
} 

void StepSequencer::run() { 
    mRunSequencerThread = true; 
    while(mRunSequencerThread) { 
     mCurrentTime = std::chrono::system_clock::now(); 
    mMutex.lock(); 
     if (std::chrono::duration_cast<std::chrono::seconds>(mCurrentTime - mLastBeatTime).count() > mSecondsPerBeat) { 
     mSequencerPlayhead++; 
     mSequencerPlayhead = mSequencerPlayhead % mNumberOfBeatBins; 
     playNote(mSequencerPlayhead); 
      mLastBeatTime = std::chrono::system_clock::now(); 
    } 
    mMutex.unlock(); 
    this_thread::sleep_for(std::chrono::milliseconds(1)); 
    } 
} 

void StepSequencer::setBeatsPerMinute(float bpm) { 
    mMutex.lock(); 
    mBeatsPerMinute = bpm; 
    if(mBeatsPerMinute > 0) { 
     mSecondsPerBeat = 60.0/mBeatsPerMinute; 
    } 
    else { 
    mSecondsPerBeat = 1; 
    } 
mMutex.unlock(); 
} 

void StepSequencer::addNote(int noteValue, int beatIndex) { 
    mBeatBins[beatIndex] = noteValue; 
} 

void StepSequencer::playNote(int beatIndex) { 
    std::cout << mBeatBins[beatIndex] << std::endl; 
} 
+1

請指定_timer_更多。 –

+0

如果可以,我會 - 可以指定我的選項用於描述計時器嗎? –

+0

使用更高精度的時鐘。 –

回答

2

std::chrono::seconds具有 'A符號整型至少35比特的' 的表示。所以你將得到一個值爲count(),它每秒只增加一次,給出60,30,20,15,12等每分鐘節拍的選項。

以毫秒爲單位工作或使用由浮點值支持的自定義持續時間。

+0

啊哈!這非常有用,似乎是我錯過的一條信息。 –

相關問題