Go言語で音を鳴らす3
背景
PythonとGoはCを介して連携ができるみたいなので,これを使えばPythonの優れた楽器的なライブラリを使えて,Goでシンセサイザーとかを簡単に鳴らせるんじゃないかと考えた.
使うサイトはこれら
環境
macOS Big Sur ver. 11.5.1(20G80) -> 12.6 (21G115)
MacBook Air M1, 2020
メモリ 8GB
Homebreq ver.3.6.3(git revision 86ac48865b7; last commit 2022-10-02)
Python 3.10.6
pip 22.2.2 from /opt/homebrew/lib/python3.10/site-packages/pip (python 3.10)
pyaudio-0.2.12
Step1 Python3, pipのインストール
MacBook-Air ~ % brew install python3
これでpython3のインストールは完了する.
MacBook-Air ~ % curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2500k 100 2500k 0 0 5982k 0 --:--:-- --:--:-- --:--:-- 5968k
MacBook-Air ~ % python3 get-pip.py
Defaulting to user installation because normal site-packages is not writeable
Collecting pip
Downloading pip-22.2.2-py3-none-any.whl (2.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 1.7 MB/s eta 0:00:00
Installing collected packages: pip
WARNING: The scripts pip, pip3 and pip3.8 are installed in '/Users/usrname/Library/Python/3.8/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-22.2.2
[notice] A new release of pip available: 20.2.3 -> 22.2.2
[notice] To update, run: /Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip
WARNING: The scripts pip, pip3 and pip3.8 are installed in '/Users/usrname/Library/Python/3.8/bin' which is not on PATH.
って書いてあるからそのディレクトリを見てみよう.
MacBook-Air Library % cd Python
MacBook-Air Python % ls
3.8
MacBook-Air Python % cd 3.8
MacBook-Air 3.8 % ls
bin lib
MacBook-Air 3.8 % cd bin
MacBook-Air bin % ls
pip pip3 pip3.8
ちゃんとあった.
一番下のやつの[notice]の
/Library/Developer/CommandLineTools/usr/bin
のところにもなんかpipいるけどひとまず無視.
pipもインストールできたっぽい.
そしたらPATHを通そう.PATHについての詳しい説明はこのサイトに投げる.
MacBook-Air ~ % ls .zshrc
.zshrc
MacBook-Air ~ % open .zshrc
export PATH=$PATH:/Users/usrname/Library/Python/3.8/binを.zshrcに追加.
MacBook-Air ~ % source .zshrc
MacBook-Air ~ % pip3 -V
pip 22.2.2 from /opt/homebrew/lib/python3.10/site-packages/pip (python 3.10)
pip3にPATHが繋がっているっぽいことも確認できた.
Step2 Synthesizerの簡単な使い方
インストール
で,実際にpip3 install synthesizerしてみたらなんかエラー発生して怒られた
結構長くめんどくなりそうなので別の記事にまとめようと思う.
まぁ簡単に言うとmacOSのバージョンの問題だったから,最新のものにしとけば大丈夫.環境のところに矢印つけて変化させてたのはこれが理由.
MacBook-Air ~ % pip3 install synthesizer
Collecting synthesizer
Using cached synthesizer-0.2.0.tar.gz (5.4 kB)
Preparing metadata (setup.py) ... done
Collecting enum34>=1.1.6
Using cached enum34-1.1.10-py3-none-any.whl (11 kB)
Collecting numpy>=1.13.3
Using cached numpy-1.23.3-cp310-cp310-macosx_11_0_arm64.whl (13.3 MB)
Collecting scipy>=0.19.1
Downloading scipy-1.9.1-cp310-cp310-macosx_12_0_arm64.whl (29.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 29.9/29.9 MB 1.8 MB/s eta 0:00:00
Building wheels for collected packages: synthesizer
Building wheel for synthesizer (setup.py) ... done
Created wheel for synthesizer: filename=synthesizer-0.2.0-py2.py3-none-any.whl size=5879 sha256=15890d8e09df9a0f8dffa533f7b3c65801add56646aca44b5c13811e677b3147
Stored in directory: /Users/usrname/Library/Caches/pip/wheels/00/07/f7/f6919b025939c72812e61e71bf3316e38bb4f740f661d70a18
Successfully built synthesizer
Installing collected packages: enum34, numpy, scipy, synthesizer
Successfully installed enum34-1.1.10 numpy-1.23.3 scipy-1.9.1 synthesizer-0.2.0
sin波の出力
from synthesizer import Player, Synthesizer, Waveform
# オーディオデバイス出力用クラス
player = Player()
# 引数を指定しなければデフォルトの出力デバイスが選択されます
player.open_stream()
# player.enumerate_device() でデバイスの一覧を表示できます
# player.open_stream(device_name="UA-25EX") のように出力デバイスを指定可能です
synth = Synthesizer(osc1_waveform=Waveform.sine, osc1_volume=1.0, use_osc2=False)
player.play_wave(synth.generate_constant_wave(440.0, 1.0))
でスピーカーを鳴らそうとしたら
MacBook-Air synthe % python3 synthe.py
Traceback (most recent call last):
File "/Users/usrname/synthe/synthe.py", line 6, in <module>
player.open_stream()
File "/opt/homebrew/lib/python3.10/site-packages/synthesizer/player.py", line 38, in open_stream
raise ImportError("Failed to import pyaudio, please install pyaudio")
ImportError: Failed to import pyaudio, please install pyaudio
って怒られた.どうやらpyaudioもインストールしなくてはいけないらしい.
pyaudioのインストール
brew updateで躓いたので,それは別の記事にまとめる.
躓いてなければ.
brew update
brew install portaudio
pip3 install pyaudio
でできると思う.
でbrew updateを解決したから進んでみると
MacBook-Air ~ % brew install portaudio
Warning: portaudio 19.7.0 is already installed and up-to-date.
To reinstall 19.7.0, run:
brew reinstall portaudio
portaudioのinstallについては問題なし,というか既に入ってたみたいに言われた.
でもpyaudioのinstallでも怒られてしまった.
今まで同様,別の記事にまとめる.
結果的にはpyaudio-0.2.12がインストールできた.
ちゃんと
MacBook-Air synthe % python3 synthe.py
したら,ポーって音がでた.
これでpyaudioを使ってシンセを鳴らすことまでは可能になった.
Step3 GoからPythonを呼ぶ
ひとまず,サイト内で完成コードとして載せられてるやつをいじっていく.
package main
// #cgo CFLAGS: -I/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9
// #cgo LDFLAGS: -L/Library/Frameworks/Python.framework/Versions/3.9/lib -lpython3.9
// #include <Python.h>
import "C"
func main() {
// 最後にPythonインタプリタ終了
defer C.Py_Finalize()
// Pythonインタプリタの初期化
C.Py_Initialize()
// GoのstringをCのcharに型変換(変換しないとPyRun_SimpleStringに型合ってないよって怒られる)
// cannot use "print(\"Hello, World!\")" (type string) as type *_Ctype_char in argument to _Cfunc_PyRun_SimpleString
pyCodeStr := `print("Hello, World!")`
pyCodeChar := C.CString(pyCodeStr)
// Pythonコードを文字列として受け取ってインタプリタ上で実行
C.PyRun_SimpleString(pyCodeChar)
}
そのままvscodeにコピペすると
fatal error: 'Python.h' file not found go
って<Pythin.h>のところに赤波線くらう.
まず,cgoが指してるパスのところを見ると,
Python.frameworkなんてないんだが.
らしい.じゃあ自分のPythonがある位置に書き換えないと.
/Library/Developer/CommandLineTools/usr/binに置いてあった気がする.
あった.
LDFLAGSのlibの方は/Users/usrname/Library/Python/3.9にあった.
MacBook-Air ~ % cd Library/Python
MacBook-Air Python % ls
3.8 3.9
MacBook-Air Python % cd 3.9
MacBook-Air 3.9 % ls
bin lib
MacBook-Air 3.9 % cd lib
MacBook-Air lib % ls -A
python
-lpython3.9ってなんのことなんだろう.
とりあえずもうちょい深くまでディレクトリ掘ってみる.
MacBook-Air lib % cd python
MacBook-Air python % ls
site-packages
MacBook-Air python % cd site-packages
MacBook-Air site-packages % ls
pip pip-22.2.2.dist-info
MacBook-Air site-packages % cd pip
MacBook-Air pip % ls
__init__.py __pip-runner__.py _vendor
__main__.py _internal py.typed
特になさそう.
-lpython3.9で検索しても全然ヒットしないし,とりあえず pythonで進めてみよう.
package main
// #cgo CFLAGS: -I/Library/Developer/CommandLineTools/usr/bin/python3.9
// #cgo LDFLAGS: -L/Users/usrname/Library/Python/3.9/lib python
// #include <Python.h>
import "C"
func main() {
// 最後にPythonインタプリタ終了
defer C.Py_Finalize()
// Pythonインタプリタの初期化
C.Py_Initialize()
// GoのstringをCのcharに型変換(変換しないとPyRun_SimpleStringに型合ってないよって怒られる)
// cannot use "print(\"Hello, World!\")" (type string) as type *_Ctype_char in argument to _Cfunc_PyRun_SimpleString
pyCodeStr := `print("Hello, World!")`
pyCodeChar := C.CString(pyCodeStr)
// Pythonコードを文字列として受け取ってインタプリタ上で実行
C.PyRun_SimpleString(pyCodeChar)
}
修正したら<Python.h>の波線は消えた.
ビルドしてみよう.
MacBook-Air sound_wav % go build -o main
go build sound_wav: invalid flag in #cgo LDFLAGS: python
LDFLAGS,ちょうどわからなかったところが怒られた.
怒られ内容で検索かけたらこれが見つかった.
なんか-lをつけましょうって言われてる.
とりあえずつけてやってみよう.
// #cgo CFLAGS: -I/Library/Developer/CommandLineTools/usr/bin/python3.9
// #cgo LDFLAGS: -L/Users/usrname/Library/Python/3.9/lib -lpython
// #include <Python.h>
MacBook-Air sound_wav % go build -o main
# sound_wav
./main.go:5:11: fatal error: 'Python.h' file not found
#include <Python.h>
^~~~~~~~~~
1 error generated.
なんか違う怒られ方したんだが…
さっきのでは出てこなくてここで出てきてる.
降参して質問してきた.
まとめると,cgoのPATHがやっぱり違ってて,次のコマンドで「Pythonがライブラリをインポートしたときにそのライブラリがあるかどうか探す順番を表示」させる.
MacBook-Air ~ % python3 -c "import sys, pprint; pprint.pprint(sys.path)"
['',
'/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python310.zip',
'/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10',
'/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/lib-dynload',
'/opt/homebrew/lib/python3.10/site-packages']
その探しに行くPATHの順番はsys.pathの値になっているのでこのようなコマンドになる.
で,この結果と完成コードとして載ってたものを見比べて次のようにした.
// #cgo CFLAGS: -I/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/include/python3.10
// #cgo LDFLAGS: -L/opt/homebrew/Cellar/python@3.10/3.10.6_2/Frameworks/Python.framework/Versions/3.10/lib -lpython3.10
// #include <Python.h>
これでビルドしてみると,今までのPython.hが見つからないというエラーは消えた,
ただし別のエラーが生えた.
MacBook-Air sound_wav % go build -o main
# sound_wav
Undefined symbols for architecture arm64:
"_Pa_CloseStream", referenced from:
_main in _x003.o
"_Pa_GetDefaultOutputDevice", referenced from:
_main in _x003.o
"_Pa_GetDeviceInfo", referenced from:
_main in _x003.o
"_Pa_Initialize", referenced from:
_main in _x003.o
"_Pa_OpenStream", referenced from:
_main in _x003.o
"_Pa_StartStream", referenced from:
_main in _x003.o
"_Pa_StopStream", referenced from:
_main in _x003.o
"_Pa_Terminate", referenced from:
_main in _x003.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
この記事が気に入ったらサポートをしてみませんか?