Created
December 4, 2012 12:37
-
-
Save bolero-MURAKAMI/4203389 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// サンプル数 : デフォルト = 44100 | |
#ifndef CMP_SAMPLE | |
# define CMP_SAMPLE 44100 | |
#endif | |
// 長さの基準[sec] : デフォルト = 1 | |
#ifndef CMP_LENGTH | |
# define CMP_LENGTH 1 | |
#endif | |
// 基本音周波数[Hz] : デフォルト = 440(ラ音) | |
#ifndef CMP_BASE | |
# define CMP_BASE 440 | |
#endif | |
#include <cstddef> | |
#include <cstdint> | |
#include <climits> | |
#include <sprout/compost.hpp> | |
#include <sprout/array.hpp> | |
#include <sprout/index_tuple.hpp> | |
#include "wave_io.hpp" | |
namespace cmp = sprout::compost; | |
static constexpr std::size_t sample_per_sec = CMP_SAMPLE; | |
static constexpr double length = CMP_LENGTH; | |
static constexpr double base = CMP_BASE; | |
static constexpr std::size_t one_size = static_cast<std::size_t>(length * sample_per_sec); | |
// | |
// 音符 | |
// | |
struct note { | |
public: | |
double length; | |
double semitones; | |
double amplitude; | |
}; | |
// | |
// 1音を生成 | |
// | |
constexpr auto sounded_one(note const& n) | |
-> decltype( | |
cmp::waves::sinusoidal(cmp::equal_temperament_value(n.semitones) * base / sample_per_sec, n.amplitude) | |
| cmp::ranges::taken(static_cast<std::size_t>(n.length * one_size)) | |
) | |
{ | |
return cmp::waves::sinusoidal(cmp::equal_temperament_value(n.semitones) * base / sample_per_sec, n.amplitude) | |
| cmp::ranges::taken(static_cast<std::size_t>(n.length * one_size)) | |
; | |
} | |
// | |
// 音を生成 | |
// | |
template<typename Note> | |
constexpr auto sounded_x(Note const& note) | |
-> decltype(sounded_one(note)) | |
{ | |
return sounded_one(note); | |
} | |
template<typename Note, typename... Tail> | |
constexpr auto sounded_x(Note const& note, Tail const&... tail) | |
-> decltype(sounded_one(note) | cmp::ranges::jointed(sounded_x(tail...))) | |
{ | |
return sounded_one(note) | cmp::ranges::jointed(sounded_x(tail...)); | |
} | |
template<typename Score, sprout::index_t... Indexes> | |
constexpr auto sounded_i(Score const& score, sprout::index_tuple<Indexes...>) | |
-> decltype(sounded_x(score[Indexes]...)) | |
{ | |
return sounded_x(score[Indexes]...); | |
} | |
template<typename Score> | |
constexpr auto sounded(Score const& score) | |
-> decltype(sounded_i(score, sprout::index_range<0, Score::static_size>::make())) | |
{ | |
return sounded_i(score, sprout::index_range<0, Score::static_size>::make()); | |
} | |
int main(int argc, char* argv[]) { | |
namespace cmp = sprout::compost; | |
// スコア | |
constexpr sprout::array<note, CMP_SCORE0_NUM> score0{CMP_SCORE0}; | |
constexpr sprout::array<note, CMP_SCORE1_NUM> score1{CMP_SCORE1}; | |
// 波形の生成(変換前) | |
constexpr auto src = sounded(score0) | cmp::effects::superposed(sounded(score1)); | |
constexpr std::size_t size = sprout::size(src); | |
typedef double src_elem_t; | |
typedef sprout::array<src_elem_t, size> src_t; | |
typedef std::int16_t wav_elem_t; | |
typedef sprout::array<wav_elem_t, size> wav_t; | |
// WAVE の情報 | |
constexpr sprout::compost::sources::info_type wav_info{ | |
1, // フォーマットID | |
1, // チャンネル数 | |
sample_per_sec, // サンプリングレート | |
sample_per_sec * sizeof(wav_elem_t), // データ速度 (Byte/sec) | |
sizeof(wav_elem_t), // ブロックサイズ (Byte/sample*チャンネル数) | |
sizeof(wav_elem_t) * CHAR_BIT, // サンプルあたりのビット数 (bit/sample) | |
size // 要素数 | |
}; | |
// 波形の生成 | |
constexpr wav_t wav_data = | |
src | |
| cmp::formats::as_pcm_wave16 // 16bitWAVE に変換 | |
| cmp::ranges::copied // 任意のコンテナに変換可能にする | |
; | |
// ================ ここまでコンパイル時 ================ | |
// WAVE ファイルに出力 | |
char const* filename = argc >= 2 ? argv[1] : "sine_performer.wav"; | |
output_wav(filename, wav_info, wav_data); | |
// dsp デバイスのセットアップ | |
int fd = setup_dev_dsp(wav_info); | |
if (fd < 0) { | |
return 0; | |
} | |
// dsp デバイスに書き込み | |
write_dev_dsp(fd, wav_data.data(), wav_data.size() * sizeof(wav_elem_t)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment