Skip to content

Instantly share code, notes, and snippets.

@algon-320
Last active May 8, 2017 13:56
Show Gist options
  • Save algon-320/2ce97a41f5171fe2d8ca882dbde167d8 to your computer and use it in GitHub Desktop.
Save algon-320/2ce97a41f5171fe2d8ca882dbde167d8 to your computer and use it in GitHub Desktop.
WAVファイルを書き出す (c++版)
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <fstream>
#include <cmath>
// 44100 Hz / 16 bit / ステレオ のリニアPCM
#define SAMPLING_RATE (44100)
#define CHANNEL (2)
#define BIT_PER_SAMPLE (16)
#define FILE_NAME "44100_16_2_lpcm.wav"
struct wave_header {
unsigned char riff[4];
unsigned int file_bytes;
unsigned char type[4];
unsigned char fmt[4];
unsigned int fmt_bytes;
unsigned short format_id;
unsigned short channel;
unsigned int sampling;
unsigned int bytes_per_sec;
unsigned short block_size;
unsigned short bit_per_sample;
unsigned char data[4];
unsigned int data_bytes;
wave_header(const short ch, const int sampling_rate, const short bps) {
memcpy(riff, "RIFF", 4);
file_bytes = 44 - 8;
memcpy(type, "WAVE", 4);
memcpy(fmt, "fmt ", 4);
fmt_bytes = 16;
format_id = 1;
channel = ch;
sampling = sampling_rate;
bytes_per_sec = sampling_rate * ch * bps / 8;
block_size = ch * bps;
bit_per_sample = bps;
memcpy(data, "data", 4);
data_bytes = 0;
}
std::vector<unsigned char> pack() {
std::vector<unsigned char> ret(44);
unsigned int pos=0;
memcpy(&ret[pos], riff, sizeof(riff)); pos+=sizeof(riff);
memcpy(&ret[pos], &file_bytes, sizeof(file_bytes)); pos+=sizeof(file_bytes);
memcpy(&ret[pos], type, sizeof(type)); pos+=sizeof(type);
memcpy(&ret[pos], fmt, sizeof(fmt)); pos+=sizeof(fmt);
memcpy(&ret[pos], &fmt_bytes, sizeof(fmt_bytes)); pos+=sizeof(fmt_bytes);
memcpy(&ret[pos], &format_id, sizeof(format_id)); pos+=sizeof(format_id);
memcpy(&ret[pos], &channel, sizeof(channel)); pos+=sizeof(channel);
memcpy(&ret[pos], &sampling, sizeof(sampling)); pos+=sizeof(sampling);
memcpy(&ret[pos], &bytes_per_sec, sizeof(bytes_per_sec)); pos+=sizeof(bytes_per_sec);
memcpy(&ret[pos], &block_size, sizeof(block_size)); pos+=sizeof(block_size);
memcpy(&ret[pos], &bit_per_sample, sizeof(bit_per_sample)); pos+=sizeof(bit_per_sample);
memcpy(&ret[pos], data, sizeof(data)); pos+=sizeof(data);
memcpy(&ret[pos], &data_bytes, sizeof(data_bytes)); pos+=sizeof(data_bytes);
return ret;
}
};
class wave {
public:
wave() : wh(CHANNEL, SAMPLING_RATE, BIT_PER_SAMPLE), output_file_name(FILE_NAME) {}
bool output() {
wh.data_bytes = wave_data.size() * sizeof(signed short);
wh.file_bytes = 44 + wh.data_bytes - 8;
std::vector<unsigned char> file_bytes(wh.file_bytes + 8);
std::vector<unsigned char> header = wh.pack();
memcpy(&file_bytes[0], &header[0], 44);
memcpy(&file_bytes[44], &wave_data[0], wh.data_bytes);
std::ofstream fout;
fout.open(output_file_name, std::ios::out|std::ios::binary|std::ios::trunc);
if (!fout) {
std::cout << "File opening error" << std::endl;
return false;
}
fout.write((char*)&file_bytes[0], sizeof(unsigned char) * file_bytes.size());
fout.close();
return true;
}
void gen_wav_sin_ceg() {
const int length = 3; // [sec]
wave_data = std::vector<signed short>(SAMPLING_RATE * CHANNEL * length, 0);
double unit_c = 261.626 / SAMPLING_RATE * 2 * acos(-1); // ド
double unit_e = 329.628 / SAMPLING_RATE * 2 * acos(-1); // ミ
double unit_g = 391.995 / SAMPLING_RATE * 2 * acos(-1); // ソ
for(int i=0; i<SAMPLING_RATE * length; i++) {
wave_data[i*CHANNEL+0] += sin(unit_c*i) * 3000;
wave_data[i*CHANNEL+0] += sin(unit_e*i) * 3000;
wave_data[i*CHANNEL+(CHANNEL==2)] += sin(unit_c*i) * 3000;
wave_data[i*CHANNEL+(CHANNEL==2)] += sin(unit_g*i) * 3000;
}
}
void gen_wav_rect_ceg() {
const int length = 3; // [sec]
wave_data = std::vector<signed short>(SAMPLING_RATE * CHANNEL * length, 0);
double unit_c = 261.626 / SAMPLING_RATE * 2 * acos(-1); // ド
double unit_e = 329.628 / SAMPLING_RATE * 2 * acos(-1); // ミ
double unit_g = 391.995 / SAMPLING_RATE * 2 * acos(-1); // ソ
for(int i=0; i<SAMPLING_RATE * length; i++) {
wave_data[i*CHANNEL+0] += ((sin(unit_c * i)) > 0 ? 1 : -1) * 2000;
wave_data[i*CHANNEL+0] += ((sin(unit_e * i)) > 0 ? 1 : -1) * 2000;
wave_data[i*CHANNEL+(CHANNEL==2)] += ((sin(unit_c * i)) > 0 ? 1 : -1) * 2000;
wave_data[i*CHANNEL+(CHANNEL==2)] += ((sin(unit_g * i)) > 0 ? 1 : -1) * 2000;
}
}
private:
wave_header wh;
std::vector<signed short> wave_data;
const std::string output_file_name;
};
int main() {
wave wav;
// wav.gen_wav_sin_ceg();
wav.gen_wav_rect_ceg();
if(!wav.output()) return -1;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment