はじめに
- 音楽にかける簡易的なエフェクターをC++で作ってみました
- ここの内容はgithubでも公開しています
- 高校2年生の頃のプログラムをつぎはぎで拡張しているので、非効率なところがあるかもしれません
- 初投稿です
条件
wavファイルは 16bit 2chのみ
github.ioのページ
ここからヘッダーファイル(Music.h)をダウンロードできます
主な機能と例
1.そのまま出力
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Export(2); //チャンネル数 1でモノラル
//wd.Export(2,"Example2.wav"); //のように名前指定可
wd.Dispose(); //破棄
2.切り取り
配列を切り取り、ヘッダーのファイルサイズ情報を書き換える
CutCopy関数だと、別の変数に保存できる
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Cut(40.7, 43.8); //始点と終点を秒数で指定
/*
WaveData wd2 = wd.CutCopy(40.7,43.8); //別の変数にコピー
*/
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
3.再生速度変更
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Speed(1.5,-6); //再生速度(倍率) ピッチを指定 倍率にマイナスを付けると逆再生
//wd.Speed(PITCH(4),4); 再生速度をピッチに合わせる場合は、PITCH(ピッチ)のマクロを推奨
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
4.リバーブ(低負荷)
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.AlgorithmicReverb(300, 0.6, 0.6); //遅延ミリ秒 倍率 原曲に混ぜる割合
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
5.畳み込みリバーブ
畳み込みリバーブ
※別途IRデータをネットから探してダウンロードしてください
4~5分の曲で20~30秒かかります
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.LRdel(1000); //片側をすこし遅延 これを付けると音が広がったように感じる?
wd.ConvolutionReverb("IR.wav", 0.4,150);//IRファイル(16bit 2ch wav) 原曲に混ぜる割合 x以下の周波数無効
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
6.調を変更
短調→長調 長調→短調 など
以下は、短調→長調 調号が♭1つの例
転調には対応していません
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Custom_Scale(MAJOR_SCALE,-1); //ピッチ変更用配列(int[12]) 調号数(#×1 ♭×-1)
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
追記:+演算子(曲を結合)と、切り取って保存できるCutCopy()を作ったので、転調対応バージョンの例を載せます
#include "Music.h"
WaveData wd = WaveData("Example.wav");
//192秒目で転調する例
WaveData wd1 = wd.CutCopy(0, 192); //転調前まで切り取って保存
WaveData wd2 = wd.CutCopy(192, wd.Time()); //転調後から最後まで切り取って保存
wd1.Custom_Scale(MINOR_SCALE, 2); //ニ長調を(#×2)をニ短調(♭×1)へ
wd2.Custom_Scale(MINOR_SCALE, -3); //(1音上がった)転調後の変ホ長調(♭×3)を変ホ短調(♭×6)へ
wd1 = wd1 + wd2; //結合
wd1.Export(2);
wd.Dispose();
wd1.Dispose();
wd2.Dispose();
元の調の調号数 $p$ と、転調後のピッチの増加量(半音$q$個)が分かれば、転調後の調号数 $r$ が求まります
$r=((p+7q+6)$ mod $12) - 6$
上の例だと、$p=2$ $q=1$ $r=-3$ になります
7.フランジャー
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Flanger(1,0.5);//スピード 原曲に混ぜる割合
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
8.コンプレッサー
$ y=f(t)|f(t)|^{a-1}$
音割れ注意
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Compressor(0.25);//波形の振幅を何乗するか
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
9.ボイスキャンセラー
$ y=\frac{f_L(t)-f_R(t)}{2}$
中央にボーカルがいれば削除できる
モノラル音源になる
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Voicecanseller();
wd.LRdel(1000); //モノラルさを軽減する場合はこれを後に入れる
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
10.声を抽出
中央がボーカルのみならうまくいく
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.CenterMultiplier(5); //引数が大きいほど音が残りにくい 1~10位がいい?
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
11.サンプリング周波数変更 (ダウンサンプリング)
3.再生速度変更 で再生速度を$\frac{1}{x}$倍したあとに、ヘッダー内のサンプリング周波数を$x$倍に書き換える
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Quality(8000); //サンプリング周波数を指定
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
12.エイリアン風
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Alien(1024, 0.1, 0.5, 1.5,1); //1フレームの長さ フレーム間の増加速度 最小速度 最大速度 開始速度
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
13.多重加速
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Multiple(3, 10); //重なる場所(秒) 速度の差(%)
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
その他
引数はソースコード内のsummaryを参照してください
14.サンプリングレートだけ変更 Rate
15.異なるピッチを重ねる Harmony
16.オルゴール風 Orgel ※wd.Edit(Orgel, 24, wd.Getsample(),8192); //の形でつかう
17.粗くする Rough
18.拍子入れ替え Swap (Youtubeにあったので作ってみた)
19. +演算子 (曲を繋げる)
以下解析用
19.サンプリングレート抽出 int Getsample
20.BPM検出 double BPM
$2^k$($k$...自然数)倍ずれることがある
21.調検出 std::string Scale
英語(C E#m G♭ など) 結構不正確
参考