simple sampler by raspberrypi and openFrameworks

raspberrypiとopenframeworksを使って簡単なsamplerを作った.

環境

raspberrypi
openFrameworks(for linux)

addon

ofxGPIO

GPIO setting

Raspberry-Pi-GPIO-pinouts.png

これ


ボタンを押した時に
GPIO番号 : 役割
GPIO14 : 録音開始/録音停止ボタン
GPIO15 : 再生開始/一時停止ボタン
GPIO18 : 再生位置を最初に戻すボタン
の動作を行う様に割り当てた.

具体的な配線は以下の通り:

PIN番号 : 色 : 役割
1 : 赤 : 3.3V
6 : 黒 : GND
8 : 黄 : 赤ボタン > GPIO14, 録音開始/録音停止ボタン
10 : 青 : 青ボタン > GPIO15, 再生開始/一時停止ボタン
12 : 黒 : 黒ボタン > GPIO18, 再生位置を最初に戻すボタン

IMG_4339.jpg
IMG_4340.jpg
IMG_4341.jpg
IMG_4342.jpg
IMG_4343.jpg

codes

#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){
    ofSetupOpenGL(1024,768,OF_WINDOW);          // <-------- setup the GL context

    // this kicks off the running of my app
    // can be OF_WINDOW or OF_FULLSCREEN
    // pass in width and height too:
    ofRunApp(new ofApp());

}
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0);
    gpioRececec.setup("14");
    gpioRececec.export_gpio();
    gpioRececec.setdir_gpio("in");
    gpioPlay.setup("15");
    gpioPlay.export_gpio();
    gpioPlay.setdir_gpio("in");
    gpioBack.setup("18");
    gpioBack.export_gpio();
    gpioBack.setdir_gpio("in");

    soundStream.printDeviceList();
    soundStream.setInDeviceID(0);
    soundStream.setOutDeviceID(1);
    soundStream.setup(this, 2, 1, SampleRate, BufferSizeMax, 4);

    mode = 0;

    recPos = 0;
    playPos = 0;
    recSize = 0;
}

//--------------------------------------------------------------
void ofApp::update(){
    gpioRececec.getval_gpio(recButton);
    gpioPlay.getval_gpio(playButton);
    gpioBack.getval_gpio(backButton);
    //ofLog()<<state_button;
    cout<<"R";
    cout<<recButton;
    cout<<"_P";
    cout<<playButton;
    cout<<"_B";
    cout<<backButton<<endl;

    if(recButton=="1"){
        if(mode==1){    //stop recording
            mode = 0;
            recSize = recPos;
        }else{          //start recording
            mode = 1;
            recPos = 0;
            float buffer[BufferSizeMax] = {};
        }
        playPos = 0;
        usleep(1000000);
    }else if(playButton=="1"){
        if(mode==2){    //pause
            mode = 0;
        }else{          //play (in the middle)
            mode = 2;
        }
        usleep(1000000);
    }else if(backButton=="1"){
        playPos = 0;    //return to the initial position
        //usleep(1000000);
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    if(mode == 0) {
        ofBackground(0);
        ofSetColor(255);
    }else if(mode == 1) {
        ofBackground(255, 0, 0);
        ofSetColor(255);
        cout<<"recording"<<endl;
    }else if(mode == 2) {
        ofBackground(0, 0, 255);
        ofSetColor(255);
        cout<<"playing"<<endl;
    }

    int ratio = BufferSizeMax / ofGetWidth();
    for (int i = 0; i < recSize; i+=ratio){
        ofDrawLine(i/ratio, ofGetHeight()/2,  i/ratio, ofGetHeight()/2+buffer[i]*500.0f);
    }

    if(mode==2){
        ofSetColor(0);
        for (int i = 0; i < playPos; i+=ratio){
            ofDrawLine(i/ratio, ofGetHeight()/2,  i/ratio, ofGetHeight()/2+buffer[i]*500.0f);
        }
    }
}

//--------------------------------------------------------------
void ofApp::audioIn(float * input, int bufferSize, int nChannels){
    if (mode == 1) {
        for (int i = 0; i < bufferSize*nChannels; i++){
            if(recPos<BufferSizeMax){
                buffer[recPos] = input[i];
                recPos++;
                recSize = recPos;
            } else {
                recSize = BufferSizeMax;
                mode = 0;
            }

        }
    }
}

void ofApp::audioOut(float *output, int bufferSize, int nChannels){
    if (mode == 2) {
        for (int i = 0; i < bufferSize; i++) {
            if(playPos<recSize){
                for(int n=0; n<nChannels; n++){
                    output[nChannels*i+n] = buffer[playPos];
                }
                playPos++;
            } else {
                mode = 0;
                playPos = 0;
            }
        }
    }
}


//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if(key=='r'){
        if(mode==1){    //stop recording
            mode = 0;
            recSize = recPos;
        }else{          //start recording
            mode = 1;
            recPos = 0;
            float buffer[BufferSizeMax] = {};
        }
        playPos = 0;
    }else if(key=='p'){
        if(mode==2){    //pause
            mode = 0;
        }else{          //play (in the middle)
            mode = 2;
        }
    }else if(key=='P'){
        playPos = 0;    //return to the initial position
    }
}
#pragma once

#include "ofMain.h"
#include "ofxGPIO.h"

class ofApp : public ofBaseApp{

    public:
    void setup();
    void update();
    void draw();

    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    void audioIn(float * input, int bufferSize, int nChannels);
    void audioOut(float * output, int bufferSize, int nChannels);

    static const int SampleRate = 48000;
    static const int BufferSizeMax = SampleRate * 5;

    ofRtAudioSoundStream soundStream;
    float buffer[BufferSizeMax];
    int recPos;
    int recSize;
    int playPos;
    int mode; //0:off, 1:recording, 2:play
    GPIO gpioRec;
    string recButton;
    GPIO gpioPlay;
    string playButton;
    GPIO gpioBack;
    string backButton;
};

codeが雑だなーとは思うけど, すみません.
あとでgitで直します.

git

https://github.com/KeitaSumiya/raspberrypi/tree/master/simple_sampler/src

結果