2021-08-16
Electronics, openFrameworks, Raspberrypi, Sound
simple sampler by raspberrypi and openFrameworks
raspberrypiとopenframeworksを使って簡単なsamplerを作った.
環境
raspberrypi openFrameworks(for linux)
addon
ofxGPIO
GPIO setting
これ で ボタンを押した時に GPIO番号 : 役割 GPIO14 : 録音開始/録音停止ボタン GPIO15 : 再生開始/一時停止ボタン GPIO18 : 再生位置を最初に戻すボタン の動作を行う様に割り当てた.
具体的な配線は以下の通り:
PIN番号 : 色 : 役割 1 : 赤 : 3.3V 6 : 黒 : GND 8 : 黄 : 赤ボタン > GPIO14, 録音開始/録音停止ボタン 10 : 青 : 青ボタン > GPIO15, 再生開始/一時停止ボタン 12 : 黒 : 黒ボタン > GPIO18, 再生位置を最初に戻すボタン
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で直します.