16bit 2ch のwavファイル
・標準ライブラリだけで作りました
・C++用簡易音楽エフェクターのヘッダーファイルです
・20種類位のエフェクターをかけることができます
・高校2年生の頃に作成し、定期的に拡張したものなのでメモリーの面などで効率が悪いかも
・説明のミスがあるかも
16bit 2ch のwavファイル
北朝鮮の音楽は著作権が無効らしいので使用
2.切りとり でフルの音源を切り取ってある
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Export(2); //チャンネル数 1でモノラル
//wd.Export(2,"Example2.wav"); //のように名前指定可
wd.Dispose(); //破棄
※ここだけフル音源を使用
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Cut(40.7, 43.8); //始点と終点を秒数で指定
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Speed(1.5,-6); //再生速度(倍率) ピッチを指定 再生速度をピッチに合わせる場合は、PITCH(ピッチ)のマクロを推奨 倍率にマイナスを付けると逆再生
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.AlgorithmicReverb(300, 0.6, 0.6); //遅延ミリ秒 倍率 原曲に混ぜる割合
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
畳み込みリバーブ
※別途IRデータをネットから探してダウンロードしてください (ここではOpenAIRのものを使用)
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(); //破棄
この曲は短調(ハ短調 #,♭ともに0個)なので、長調(ハ長調 #×3)に変更した例を載せる
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Custom_Scale(MAJOR_SCALE,0); //ピッチ変更用配列(int[12]) 調号数(#×1 ♭×-1)
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Flanger(1,0.5);//スピード 原曲に混ぜる割合
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
音割れ注意
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Compressor(0.25);//波形の振幅を何乗するか
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
中央にボーカルがいれば削除できる
モノラル音源になる
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Voicecanseller();
wd.LRdel(1000); //モノラルさを軽減する場合はこれを後に入れる
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
中央がボーカルのみならうまくいく
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.CenterMultiplier(5); //引数が大きいほど音が残りにくい 1~10位がいい?
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
ダウンサンプリングでしか使わないかも
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Quality(8000); //サンプリング周波数を指定
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Alien(1024, 0.1, 0.5, 1.5,1); //1フレームの長さ フレーム間の増加速度 最小速度 最大速度 開始速度
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
Youtubeによくある多重加速シリーズみたいな音
長めの音源の方が面白いと思う
#include "Music.h"
WaveData wd = WaveData("Example.wav");
wd.Multiple(3, 10); //重なる場所(秒) 速度の差(%)
wd.Export(2); //チャンネル数
wd.Dispose(); //破棄
似た機能の紹介は省略
抜けあるかも
引数はソースコードを参照してください
Youtubeにあったので作ってみた
以下解析用
2^k(k...自然数)倍ずれることがある
結構不正確
次の各2つの関数があれば良い
読み込み
WaveData(std::string fname)
{
this->fname = fname;
std::ifstream ifs(fname, std::ios::binary);
ifs.seekg(0, std::ios::end);
fileSize = ifs.tellg();
ifs.seekg(0);
char* buf = new char[fileSize];
ifs.read(buf, fileSize);
bit8 = buf[34] / 8;
for (int i = 0; i < fileSize; ++i)
{
if (i < fileSize - 4)
{
if (buf[i] == 0x64 && buf[i + 1] == 0x61 && buf[i + 2] == 0x74 && buf[i + 3] == 0x61)
{
fmt = new char[i + 8];
fsize = i + 8;
for (int j = 0;j < i + 8; j++)
{
fmt[j] = buf[j];
}
wave = BtoI(buf, i + 8,fileSize);
msize = fileSize - i - 8;
break;
}
}
}
for (int i = 0; i < msize / 2; i++)
{
maxv = std::max(maxv, abs(wave[i]) + 0.0);
}
ch = ReadN(buf, 22, 23);
sample = ReadN(buf, 24, 27);
vol_min = -pow(256, bit8) / 2;
vol_max = pow(256, bit8) / 2 - 1;
ifs.close();
if (ch != 2 && bit8 != 2) {
this->Dispose();
}
delete[] buf;
}
//private関数.
int* BtoI(char* x, int start, int len)
{
int* rt = new int[(len - start) / 2];
for (int i = start; i < len; i += 2)
{
if (x[i] < 0)
{
rt[(i - start) / 2] = x[i + 1] * 256 + x[i] + 256;
}
else
{
rt[(i - start) / 2] = x[i + 1] * 256 + x[i];
}
}
return rt;
}
//使用例.
WaveData wd = WaveData("ファイル名.wav");
出力
void Export(int cch, std::string name)
{
int* rt;
switch (cch)
{
case 1:
rt = new int[msize / 4];
for (int i = 0; i < msize / 2 - 1; i += 2)
{
rt[i / 2] = wave[i] / 2 + wave[i + 1] / 2;
}
wave = rt;
WriteN(1, 22, 22);
WriteN(fileSize - msize / 2 - 8, 4, 7);
WriteN(fileSize - msize / 2 - 126, fsize - 4, fsize - 1);
msize >>= 1;
break;
default:
break;
}
char* bf = ItoB(wave, vol * vol_max / maxv, msize / 2);
std::ofstream ifs(name, std::ios::binary);
ifs.write(fmt, fsize);
ifs.write(bf, msize);
delete[] bf;
}
//private関数.
char* ItoB(int* cmp, double mult, int cl)
{
char* rt = new char[cl * 2];
for (int i = 0; i < cl; ++i)
{
if (cmp[i] < 0) {
rt[i * 2 + 1] = std::max(cmp[i] * mult, vol_min + 0.0) / 256;
rt[i * 2] = cmp[i] * mult - rt[i * 2 + 1] * 256;
}
else {
rt[i * 2 + 1] = std::min(cmp[i] * mult, vol_max + 0.0) / 256;
rt[i * 2] = cmp[i] * mult - rt[i * 2 + 1] * 256;
}
}
return rt;
}
//使用例.
wd.Export(チャンネル数(1 or 2), "ファイル名.wav");