Help us understand the problem. What is going on with this article?

simple sampler by raspberrypi and openFrameworks

More than 1 year has passed since last update.

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

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

結果

https://youtu.be/OwPcFcb6BtM

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした