#include <iostream>
#include <cmath>
#include <random>
#include <cstdint>
#include <vector>
#include <limits>
#include <fstream>
#include <algorithm>
#include <tuple>
///Special Thanks. SoftTuner:http://w...content-available-to-author-only...o.jp/vpack/browse/person/an027069.html
typedef std::vector<std::int16_t> DType;
typedef std::tuple<double, double> PType;
typedef std::vector<PType> PVec;
typedef std::tuple<std::uint64_t,std::uint64_t, PVec> RUI;//length,wavetype,effect param.by ui.
static const std::uint64_t SampleRate = 44100;
static const double CodeHz = 110;//code A.
static const double Resolution = 100;//must set 10^N.
DType MakeVector(std::uint64_t Hz, std::uint64_t millisec) {
std::size_t DS = (1 * Hz * 1)*(static_cast<double>(millisec/1000));//1ch*SampleRate*16bit*1count.
return DType(DS);
}
bool MakeSinWave(DType& D, double Hz) {
double PI = 3.14159265358979323846;// from wikipedia jp.
//double Hz = CodeHz*Octrve;
double Div = SampleRate / Hz;//samplerate of 1hz
double Rad = (2*PI) / Div;//make 1hz delta.
for(std::size_t i=0;i<D.size();i++){
D[i] = std::sin(Rad*std::fmod(i,Div+std::numeric_limits<double>::epsilon()*2))*std::numeric_limits<DType::value_type>::max();
}
return true;
}
bool MakeSquareWave(DType& D, double Hz) {
//double Hz = CodeHz*Octrve;
double A = SampleRate / Hz;
double E = 1/ (A/2);
int S = 1;
std::size_t j = 0;
for(std::size_t i=0;i<D.size();i++){
D[i] = (std::numeric_limits<DType::value_type>::max()*S)-S;
if ((E*j) >= 1) {
j = 0;
S *= -1;
}
j++;
}
return true;
}
bool MakeTriangleWave(DType& D, double Hz) {
//double Hz = CodeHz*Octrve;
double A = SampleRate / Hz;//sample of 1hz
double B = std::numeric_limits<DType::value_type>::max()*2/(A/2);
double C = 0;
int S = 1;
for (std::size_t i=0;i<D.size();i++){
D[i] = C ;
if ((C + (B*S)) >= std::numeric_limits<DType::value_type>::max()) S *= -1;
if ((C + (B*S)) <= std::numeric_limits<DType::value_type>::min()) S *= -1;
C += (B*S);
}
return true;
}
bool MakeSawWave(DType& D,double Hz) {
//double Hz = CodeHz*Octrve;
double A = SampleRate / Hz;//sample of 1hz
double B = std::numeric_limits<DType::value_type>::max()*2/A;
double C = 0;
for (std::size_t i=0;i<D.size();i++){
D[i] = C ;
if ((C + B) >= std::numeric_limits<DType::value_type>::max()) C = std::numeric_limits<DType::value_type>::min();
C += B;
}
return true;
}
bool MakeHzNoise(DType& D, double Hz) {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> uid(0, std::numeric_limits<DType::value_type>::max() * 2);
// double Hz = CodeHz*Octrve;
double A = SampleRate / Hz;
double B = uid(mt) - std::numeric_limits<DType::value_type>::max();
double E = 1 / (A / 2);
double i = 0;
int S = 1;
std::size_t j = 0;
for(std::size_t i=0;i<D.size();i++){
D[i] = B;
j++;
if ((E*j) >= 1) {
j = 0;
B = uid(mt) - std::numeric_limits<DType::value_type>::max();
}
}
return true;
}
bool MakePerfectNoise(DType& D, std::uint8_t Octrve = 1) {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> uid(0, std::numeric_limits<DType::value_type>::max() * 2);
for(std::size_t i=0;i<D.size();i++){
D[i] = uid(mt) - std::numeric_limits<DType::value_type>::max();
}
return true;
}
RUI ShowUI() {
PVec V;
std::uint64_t ms;
double Pos = 0;
double Vol = 0;
double OP = 0;
std::uint8_t A = 0;
std::uint64_t WT = 1;
std::cout << "Welcome Pulse Generator!" << std::endl;
std::cout << "Auther is this need for SONY ACID." << std::endl;
std::cout << "Warning:output file is EASY to CRASH your EAR!!!" << std::endl;
std::cout << "Warning:Becareful for using. and the use under YOUR OWN RISK." << std::endl;
std::cout << std::endl;
std::cout << "I have some question. plz answer." << std::endl;
std::cout << "How Length Are you need? (millisec)" << std::endl;
std::cin >> ms;
std::cout << "Ask Wave Type." << std::endl;
std::cout << "1:Sin 2:Square 3:Triangle 4:Saw 5:HzNoise 6:PerfectNoise" << std::endl;
std::cin >> WT;
std::cout << "Are your use my effecter?:Yes => input y." << std::endl;
std::cin >> A;
if (!(A == 'y' || A=='Y'))return std::make_tuple(ms,WT, V);
V.push_back(std::make_tuple(Pos, Vol));
while (A == 'y' || A == 'Y') {
std::cout << "Set This Time's End Position:" << OP << "<->"<<Resolution<<"." << std::endl;
std::cin >> Pos;
Pos = std::max(OP, Pos);
Pos = std::min(Resolution, Pos);
OP = Pos;
std::cout << "Set This Time's Sample Level:0<->"<<Resolution<<"." <<"Now:"<<Vol<< std::endl;
std::cin >> Vol;
Vol = std::max(0.0, Vol);
Vol = std::min(Resolution, Vol);
V.push_back(std::make_tuple(Pos, Vol));
if (Pos >= Resolution) break;
std::cout << "Continue?:Yes => input y." << std::endl;
std::cin >> A;
}
std::cout << "End Of Question." << std::endl;
std::cout << std::endl;
std::cout << "*Info*" << std::endl;
std::cout << "Pos,Level" << std::endl;
for (auto&o : V) {
std::tie(Pos, Vol) = o;
std::cout << Pos << "," << Vol << std::endl;
}
return std::make_tuple(ms,WT, V);
}
bool WriteWaveFile(DType& D,std::uint64_t Hz, std::uint16_t Channel,const char* Name="out.wav") {
std::ofstream ofs(Name, std::ios::binary);
char RIFF[] = "RIFF";
char WAVE[] = "WAVE";
char fmt[] = "fmt ";
char data[] = "data";
std::uint32_t FSize = (44 - 8) + (D.size() * sizeof(DType::value_type));
std::uint32_t ui32 = 0;
std::uint16_t ui16 = 0;
ofs.write(RIFF, 4);
ofs.write(reinterpret_cast<const char*>(&FSize), 4);//fsize-8.
ofs.write(WAVE, 4);
ofs.write(fmt, 4);
ui32 = 16;
ofs.write(reinterpret_cast<const char*>(&ui32), 4);//fmt chunk size
ui16 = 1;
ofs.write(reinterpret_cast<const char*>(&ui16), 2);//sound type. PCM = 1.
ui16 = Channel;
ofs.write(reinterpret_cast<const char*>(&ui16), 2);//Channnel count.
ui32 = static_cast<std::uint32_t>(Hz);
ofs.write(reinterpret_cast<const char*>(&ui32), 4);//Sampling Hz.
ui32 = static_cast<std::uint32_t>(Hz*Channel*(sizeof(DType::value_type)));
ofs.write(reinterpret_cast<const char*>(&ui32), 4);//data speed??
ui16 = Channel*(sizeof(DType::value_type));
ofs.write(reinterpret_cast<const char*>(&ui16), 2);//BlockSize??
ui16 = (sizeof(DType::value_type) * 8);
ofs.write(reinterpret_cast<const char*>(&ui16), 2);//Sampling Bit.
ofs.write(data, 4);
ui32 = static_cast<std::uint32_t>(D.size()*sizeof(DType::value_type));
ofs.write(reinterpret_cast<const char*>(&ui32), 4);//Sample's ALL SIZE.max at 32bit.
ofs.write(reinterpret_cast<const char*>(&D[0]), D.size()*sizeof(DType::value_type));//WriteSamples.
return true;
}
bool MonoToStereo(DType& D) {
DType St;
for (auto& o : D) {
St.push_back(o);
St.push_back(o);
}
D = St;
return true;
}
DType Factory(std::uint64_t Type, std::uint64_t ms) {
std::uint8_t Oct = 3;
DType D=MakeVector(SampleRate,ms);
switch (Type) {
case 1:
MakeSinWave(D,CodeHz * Oct);
break;
case 2:
MakeSquareWave(D,CodeHz * Oct);
break;
case 3:
MakeTriangleWave(D,CodeHz *Oct);
break;
case 4:
MakeSawWave(D,CodeHz *Oct);
break;
case 5:
MakeHzNoise(D,CodeHz *Oct);
break;
case 6:
MakePerfectNoise(D,CodeHz *Oct);
break;
default:
MakeSinWave(D,Oct);
break;
}
return D;
}
bool Effecter(DType& D, PVec& P) {
if (D.size() == 0) return false;
std::size_t PosA = 0;
std::size_t PosB = 0;
double Pos = 0;
double Vol = 0;
double VolA= 0;
double VolB = 0;
double VolD = 0;
for (std::size_t i = 1; i < P.size(); i++) {
std::tie(Pos, Vol) = P[i];
PosA = D.size()*(Pos / Resolution);
VolA = Vol/Resolution;
std::tie(Pos, Vol) = P[i - 1];
PosB = D.size()*(Pos / Resolution);
VolB = Vol/Resolution;
VolD = (VolA - VolB) / (PosA - PosB);
for (std::size_t j = PosB; j < PosA; j++) {
Vol = (VolB + ((VolD)*(j - PosB)));
D[j] *= Vol;
}
}
return true;
}
DType MakeVector1Hz(std::size_t Hz) {
std::size_t DS = SampleRate/Hz;
return DType(DS);
}
bool MakeSinWave1Hz(DType& D) {
double PI = 3.14159265358979323846;// from wikipedia jp.
double Delta = 360.0 / static_cast<double>(D.size()-1);
double Rad = (2 * PI) / Delta;
std::size_t i = 0;
for (std::size_t i = 0; i < D.size(); i++) {
D[i] = std::sin(Rad*std::fmod(i, Delta + std::numeric_limits<double>::epsilon() * 2))*std::numeric_limits<DType::value_type>::max();
}
return true;
}
bool MakeSquareWave1Hz(DType& D) {
double A = D.size();
double E = 1/ (A/2);
int S = 1;
std::size_t j = 0;
for(std::size_t i=0;i<D.size();i++){
D[i] = (std::numeric_limits<DType::value_type>::max()*S)-S;
if ((E*j) >= 1) {
j = 0;
S *= -1;
}
j++;
}
return true;
}
bool MakeSawWave1Hz(DType& D) {
double A = D.size();
double B = std::numeric_limits<DType::value_type>::max() * 2 / A;
double C = 0;
for (std::size_t i = 0; i<D.size(); i++) {
D[i] = C;
if ((C + B) >= std::numeric_limits<DType::value_type>::max()) C = std::numeric_limits<DType::value_type>::min();
C += B;
}
return true;
}
bool MakeTriangleWave(DType& D) {
double A = D.size();
double B = std::numeric_limits<DType::value_type>::max() * 2 / (A / 2);
double C = 0;
int S = 1;
for (std::size_t i = 0; i<D.size(); i++) {
D[i] = C;
if ((C + (B*S)) >= std::numeric_limits<DType::value_type>::max()) S *= -1;
if ((C + (B*S)) <= std::numeric_limits<DType::value_type>::min()) S *= -1;
C += (B*S);
}
return true;
}bool MakeHzNoise1Hz(DType& D, double Hz) {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> uid(0, std::numeric_limits<DType::value_type>::max() * 2);
double A = D.size();
double B = uid(mt) - std::numeric_limits<DType::value_type>::max();
double E = 1 / (A / 2);
double i = 0;
int S = 1;
for(std::size_t i=0;i<D.size();i++){
D[i] = B;
i++;
if ((E*i) >= 1) {
i = 0;
B = uid(mt) - std::numeric_limits<DType::value_type>::max();
}
}
return true;
}
bool MakePerfectNoise1hz(DType& D) {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> uid(0, std::numeric_limits<DType::value_type>::max() * 2);
for(std::size_t i=0;i<D.size();i++){
D[i] = uid(mt) - std::numeric_limits<DType::value_type>::max();
}
return true;
}
DType FM(DType& D,DType M,double FirstTheta,double SecandTheta,double Time) {
DType R;
double PI = 3.14159265358979323846;
double Rad = 180.0 / PI;
for (std::size_t i = 0; i < D.size(); i++) {
double T = (M[i % M.size()]/static_cast<double>(std::numeric_limits<DType::value_type>::max())) * std::sin((FirstTheta*Rad) + (SecandTheta*Rad)*i)*(i/static_cast<double>(D.size()));
R.push_back(D[i] * T);
}
return R;
}
/** /
DType FM(DType& D,double FirstTheta,double SecandTheta,double Time) {
//DType M = MakeVector1Hz(SecandTheta);
DType M = MakeVector(SampleRate*(SecandTheta/360.0),1000);
DType R;
double PI = 3.14159265358979323846;
double Rad = 180.0 / PI;
Make1HzSinWave(M);
for (std::size_t i = 0; i < D.size(); i++) {
//double T = (M[i % M.size()]/static_cast<double>(std::numeric_limits<DType::value_type>::max())) * std::sin((FirstTheta*Rad) + (SecandTheta*Rad)*i)*Time;
double T = (D[i % D.size()]/static_cast<double>(std::numeric_limits<DType::value_type>::max())) * std::sin((FirstTheta*Rad) + (SecandTheta*Rad)*i)*(i/static_cast<double>(D.size()));
R.push_back(D[i] * T);
}
return R;
}
/**/
bool Test() {
DType D = MakeVector(SampleRate, 1000);
MakeSinWave(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "Sin.wav");
MakeSawWave(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "Saw.wav");
MakeSquareWave(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "Square.wav");
MakeTriangleWave(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "Triangle.wav");
MakeHzNoise(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "HzNoize.wav");
MakePerfectNoise(D, CodeHz * 3);
WriteWaveFile(D, SampleRate, 1, "ParfectNoize.wav");
return true;
}
int main() {
DType D = MakeVector(SampleRate, 1000);
MakeTriangleWave(D,8);
DType M = MakeVector1Hz(2);
MakeSquareWave1Hz(M);
//WriteWaveFile(D, SampleRate, 1, "Sin.wav");
DType R = FM(D,M, 0, 1, 1);
//WriteWaveFile(R, SampleRate, 1, "FM.wav");
// Test();
/* * /
RUI R = ShowUI();
DType D = Factory(std::get<1>(R),std::get<0>(R));
Effecter(D, std::get<2>(R));
MonoToStereo(D);
WriteWaveFile(D, SampleRate, 2);
/**/
return 0;
}