LoginSignup
2
1

More than 5 years have passed since last update.

simple sampler by raspberrypi and openFrameworks

Last updated at Posted at 2017-06-26

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

main.cpp
#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());

}
ofApp.cpp
#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
    }
}
ofApp.h
#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

結果

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1