-
-
Save canonno/2209c7d68870b99d256cb4bac110b37d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"name_to_int": | |
{"ドn-3":1,"ドs-3":2,"レn-3":3,"レs-3":4,"ミn-3":5,"フn-3":6,"フs-3":7,"ソn-3":8,"ソs-3":9,"ラn-3":10,"ラs-3":11,"シn-3":12, | |
"ドn-2":13,"ドs-2":14,"レn-2":15,"レs-2":16,"ミn-2":17,"フn-2":18,"フs-2":19,"ソn-2":20,"ソs-2":21,"ラn-2":22,"ラs-2":23,"シn-2":24, | |
"ドn-1":25,"ドs-1":26,"レn-1":27,"レs-1":28,"ミn-1":29,"フn-1":30,"フs-1":31,"ソn-1":32,"ソs-1":33,"ラn-1":34,"ラs-1":35,"シn-1":36, | |
"ドn0":37,"ドs0":38,"レn0":39,"レs0":40,"ミn0":41,"フn0":42,"フs0":43,"ソn0":44,"ソs0":45,"ラn0":46,"ラs0":47,"シn0":48, | |
"ドn1":49,"ドs1":50,"レn1":51,"レs1":52,"ミn1":53,"フn1":54,"フs1":55,"ソn1":56,"ソs1":57,"ラn1":58,"ラs1":59,"シn1":60, | |
"ドn2":61,"ドs2":62,"レn2":63,"レs2":64,"ミn2":65,"フn2":66,"フs2":67,"ソn2":68,"ソs2":69,"ラn2":70,"ラs2":71,"シn2":72, | |
"ドn3":73,"ドs3":74,"レn3":75,"レs3":76,"ミn3":77,"フn3":78,"フs3":79,"ソn3":80,"ソs3":81,"ラn3":82,"ラs3":83,"シn3":84, | |
"ーs0":100,"ーn0":100,"レf-3":2,"ミf-3":4,"ソf-3":7,"ラf-3":9,"シf-3":11,"レf-2":14,"ミf-2":16,"ソf-2":19,"ラf-2":21,"シf-2":23, | |
"レf-1":26,"ミf-1":28,"ソf-1":31,"ラf-1":33,"シf-1":35,"レf0":38,"ミf0":40,"ソf0":43,"ラf0":45,"シf0":47, | |
"レf1":50,"ミf1":52,"ソf1":55,"ラf1":57,"シf1":59,"レf2":62,"ミf2":64,"ソf2":67,"ラf2":69,"シf2":71, | |
"レf3":74,"ミf3":76,"ソf3":79,"ラf3":81,"シf3":83}, | |
"int_to_hertz": | |
{"1":32.703,"2":34.648,"3":36.708,"4":38.891,"5":41.203,"6":43.654,"7":46.249,"8":48.999,"9":51.913,"10":55,"11":58.27,"12":61.735, | |
"13":65.406,"14":69.296,"15":73.416,"16":77.782,"17":82.407,"18":87.307,"19":92.499,"20":97.999,"21":103.826,"22":110,"23":116.541, | |
"24":123.471,"25":130.813,"26":138.591,"27":146.832,"28":155.563,"29":164.814,"30":174.614,"31":184.997,"32":195.998,"33":207.652, | |
"34":220,"35":233.082,"36":246.942,"37":261.626,"38":277.183,"39":293.665,"40":311.127,"41":329.628,"42":349.228,"43":369.994, | |
"44":391.995,"45":415.305,"46":440,"47":466.164,"48":493.883,"49":523.251,"50":554.365,"51":587.33,"52":622.254,"53":659.255, | |
"54":698.456,"55":739.989,"56":783.991,"57":830.609,"58":880,"59":932.328,"60":987.767,"61":1046.502,"62":1108.731,"63":1174.659, | |
"64":1244.508,"65":1318.51,"66":1396.913,"67":1479.978,"68":1567.982,"69":1661.219,"70":1760,"71":1864.655,"72":1975.533, | |
"73":2093.005,"74":2217.461,"75":2349.318,"76":2489.016,"77":2637.02,"78":2793.826,"79":2959.955,"80":3135.963,"81":3322.438, | |
"82":3520,"83":3729.31,"84":3951.066,"100":0} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////// | |
////////////////各種メソッド//////////////////// | |
/////////////////////////////////////////////// | |
//lineからのテキストには、ただの「ド」から「ドs1」まで一音につき1文字から3文字まで表記がある | |
//それらを「ド」なら「ドn4」といった、半音・全音やオクターブ情報を付与した3文字コードに置き換える | |
function score_to_name(line_text){ | |
//ファが2文字なので一文字に置き換え、最後にeeを付与し、最後であることを明示する | |
score = line_text.replace(/ファ/g,"フ") +"ee" | |
node_list = [] | |
//左から一文字ずつ読んでいく | |
for (i = 0; i < score.length-2;i++){ | |
node = score.slice(i,i+3); | |
//ドレミで始まっているか | |
type1 = /^[ドレミファソラシー]/g | |
//ドレミの次はsか数字か | |
type2 = /^[ドレミファソラシー][fs\d]/g | |
//ドレミの次にsがつくか | |
type3 = /^[ドレミファソラシー][fs]/g | |
//ドレミの後にsと数字の両方がつくか | |
type4 = /^[ドレミファソラシー][fs]\d/g | |
if (type1.test(node)){ | |
if(type2.test(node)){ | |
if(type3.test(node)){ | |
if(type4.test(node)){ | |
//ドs1みたいな表記>>そのまま格納 | |
node_list.push(node); | |
}else{ | |
//ドsみたいな表記>>オクターブ情報を付与 | |
node_list.push(node[0]+node[1]+"0"); | |
} | |
}else{ | |
//ド1みたいな表記>>ナチュラルであるnを付与 | |
node_list.push(node[0]+"n"+node[1]); | |
} | |
}else{ | |
//ドみたいな表記>>ナチュラルnとオクターブ情報を付与 | |
node_list.push(node[0]+"n"+"0"); | |
} | |
}else{ | |
//音階から始まってない>>無視して次の文字へ | |
; | |
} | |
} | |
return node_list | |
} | |
//上記で3文字コードになったものを、数値に置き換える | |
//一番低い音から1、2、3、と半音ごとに1ずつ上がる数字に置き換える | |
function node_to_int(node_list){ | |
//3文字コードと数字の対応表をインポート | |
const dict = JSON.parse(fs.readFileSync('node_dict.txt', 'utf8')); | |
name2int_dict = dict["name_to_int"] | |
//ひたすら数値化 | |
int_list = [] | |
for (i=0;i<node_list.length;i++){ | |
int_list.push(name2int_dict[node_list[i]]); | |
} | |
return int_list; | |
} | |
//上記で数値情報になったものを周波数と音の長さに置き換える | |
//key情報を引数に入れ、keyの数値分音をずらす処理も行う | |
function int_to_fre(int_list,key){ | |
//数値と周波数との対応表のインポート | |
const dict = JSON.parse(fs.readFileSync('node_dict.txt', 'utf8')); | |
int2fre_dict = dict["int_to_hertz"] | |
//ひたすら置き換える | |
fre_list = [] | |
for (i=0;i<int_list.length;i++){ | |
//「ー」の場合(数値を100としている)、ひとつ前の音のlengthを1伸ばす | |
if (int_list[i]==100){ | |
last_length = fre_list[fre_list.length-1]["length"] | |
fre_list[fre_list.length-1]["length"] = last_length + 1 | |
//普通の音の場合そのまま変換 | |
}else{ | |
fre_list.push({"frequency":int2fre_dict[int_list[i]+key],"length":1}); | |
} | |
} | |
return fre_list; | |
} | |
//obnizで出力 | |
function sound_with_obniz(line_text){ | |
//もろもろ初期設定 | |
const Obniz = require('obniz'); | |
const { text } = require("express"); | |
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます | |
//obnizと接続 | |
obniz.onconnect = async function () { | |
const speaker = obniz.wired('Speaker', {signal:0, gnd:1}); | |
//obniz上での設定パラメータ | |
key = 0; | |
BPM = 180; | |
mode_list = ['play','key','BPM'] | |
mode_idx = 300 | |
mode = mode_list[mode_idx%3] | |
// ディスプレイ処理 | |
obniz.display.clear(); // 一旦クリアする | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
// スイッチの反応を常時監視 | |
obniz.switch.onchange = async function(state) { | |
//表示がplayの時の操作 | |
if (mode == 'play'){ | |
//押したら音が鳴る | |
if (state === 'push') { | |
one_tempo = Math.round(60/2/BPM*1000); | |
node_list = score_to_name(line_text); | |
int_list = node_to_int(node_list); | |
fre_list = int_to_fre(int_list,key) | |
for (i=0;i<fre_list.length;i++){ | |
sound(fre_list[i]["frequency"],fre_list[i]["length"]); | |
} | |
obniz.display.clear(); | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//離せば何も起こらない | |
} else if (state === 'none') { | |
speaker.stop(); | |
//右にすればモードが変わる | |
} else if (state === 'right'){ | |
mode_idx += 1; | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//左にすればモードが変わる | |
} else if (state === "left"){ | |
mode_idx -= 1; | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
} | |
//表示がkeyの時の操作 | |
} else if (mode == 'key'){ | |
//押したらkeyの変更画面へ | |
if (state === 'push') { | |
mode = 'key_select' | |
obniz.display.clear(); | |
obniz.display.print(mode+"\nkey:"+key); | |
//離せば何も起こらない | |
} else if (state === 'none') { | |
speaker.stop(); | |
//右に倒せばモードが変わる | |
} else if (state === 'right'){ | |
mode_idx += 1; | |
mode = mode_list[mode_idx%3]; | |
obniz.display.clear(); | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//左に倒してもモードが変わる | |
} else if (state === "left"){ | |
mode_idx -= 1; | |
mode = mode_list[mode_idx%3]; | |
obniz.display.clear(); | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
} | |
//表示がBPMの時の操作 | |
} else if (mode == 'BPM'){ | |
//押せばBPMの設定画面になる | |
if (state === 'push') { | |
mode = 'BPM_select' | |
obniz.display.clear() | |
obniz.display.print(mode+"\nBPM:"+BPM) | |
//離せば何も起こらない | |
} else if (state === 'none') { | |
speaker.stop(); | |
//右に倒せばモードが変わる | |
} else if (state === 'right'){ | |
mode_idx += 1; | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//左に倒してもモードが変わる | |
} else if (state === "left"){ | |
mode_idx -= 1; | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
} | |
//キーセレクト画面での操作 | |
}else if (mode == 'key_select'){ | |
//押せば元の画面に戻る | |
if (state === 'push') { | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//離せば何も起こらない | |
} else if (state === 'none') { | |
speaker.stop(); | |
//右に倒せばキーが上がる | |
} else if (state === 'right'){ | |
key += 1; | |
obniz.display.clear() | |
obniz.display.print(mode+"\nkey:"+key) | |
//左に倒せばキーが下がる | |
} else if (state === "left"){ | |
key -= 1; | |
obniz.display.clear() | |
obniz.display.print(mode+"\nkey:"+key) | |
} | |
//BPM設定画面での操作 | |
} else if (mode == 'BPM_select'){ | |
//押せば元の画面に戻る | |
if (state === 'push') { | |
mode = mode_list[mode_idx%3] | |
obniz.display.clear() | |
obniz.display.print(mode + "\nkey:"+ key+" BPM:"+BPM); | |
//離せば何も起こらない | |
}else if (state === 'none') { | |
speaker.stop(); | |
//右に倒せばBPMが上がる | |
} else if (state === 'right'){ | |
BPM += 20; | |
obniz.display.clear() | |
obniz.display.print(mode+"\nBPM:"+BPM) | |
//左に倒せばBPMが下がる | |
} else if (state === "left"){ | |
BPM -= 20; | |
obniz.display.clear() | |
obniz.display.print(mode+"\nBPM:"+BPM) | |
} | |
} | |
} | |
//一つ一つの音を出力する処理 | |
function sound(fre,length){ | |
speaker.play(fre); // C5 ド | |
obniz.wait(length*one_tempo); | |
speaker.stop(); | |
obniz.wait(100); | |
} | |
} | |
} | |
/////////////////////////////////////////////// | |
/////////////ここから実行/////////////////////// | |
/////////////////////////////////////////////// | |
'use strict'; | |
const fs = require("fs"); | |
const express = require('express'); | |
const line = require('@line/bot-sdk'); | |
const { compileFunction } = require('vm'); | |
const PORT = process.env.PORT || 3000; | |
const config = { | |
channelSecret: 'チャンネルシークレットID', | |
channelAccessToken: 'チャンネルアクセストークンをここに' | |
}; | |
const app = express(); | |
//lineからくるテキスト初期値 | |
var line_text = ""; | |
//リクエストによる処理 | |
app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用 | |
app.post('/webhook', line.middleware(config), (req, res) => { | |
events = req.body.events | |
line_text = events[0].message.text | |
Promise | |
.all(req.body.events.map(handleEvent)) | |
.then((result) => res.json(result)); | |
}); | |
const client = new line.Client(config); | |
async function handleEvent(event) { | |
//テキストでない場合は無視 | |
if (event.type !== 'message' || event.message.type !== 'text') { | |
return Promise.resolve(null); | |
} | |
//lineテキストをobnizへ流し込む | |
sound_with_obniz(line_text) | |
//lineへの返信 | |
return client.replyMessage(event.replyToken, { | |
type: 'text', | |
text: 'obnizでの操作をお楽しみください' //実際に返信の言葉を入れる箇所 | |
}); | |
} | |
app.listen(PORT); | |
console.log(`Server running at ${PORT}`); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment