perl meets beats!          2011/10/14 @techno_neko
ちょっとその前に、マイクのテスト
ちょっとその前に、  マイクのテストこんな感じの音を出します。
自己紹介所属:Hokkaido.pmTwitterID:@techno_neko職種:組み込み系
今日のお題・ WAVE ファイルのお話・ ドラムマシンを作る・ デモンストレーション
今日のお題・ WAVE ファイルのお話・ ドラムマシンを作る・ デモンストレーション perl で音楽をやります!
WAVE ファイルのお話・ ファイルフォーマット・ 音階のお話・ 音をファイルに書き出す
WAVE ファイルフォーマット              こんな感じRIFF チャンク      ヘッダー  fmt チャンク    フォーマット               “data”  data チャンク     size        ...
WAVE ファイルの出力my $header =       RIFF # chunkID                      波形データ以外は、     . pack(L, ($size + 32)) # chunkSize     ....
音階のお話・ ラの音は 440Hz・ 1 オクターブ違うと倍になる・ 平均律を採用
音階のお話        Hz                   index             周波数 = 440 × 2880Hz440Hz220Hz                                         i...
音階のお話                                      index/12    Hz        周波数 = 440 × 2880Hz440Hz                      この間を 12 等分する...
音階のお話    Hz        my $freq = 440 * ( 2 ** ($index / 12) );880Hz440Hz                         この間を 12 等分する                ...
音をファイルに書き出す・ サンプリング周波数・ 量子化ビット数・ 音の長さ・ 音の周波数
例)ラの音 (440Hz) サンプリング周波数 : 44,100Hz 量子化ビット数 : 16(-32768〜+32767) 音の長さ : 1 秒               44,100 / 440+32767            1 周期...
ドラムマシンの実装・ モジュレーションのお話・ beats の出力・ groove の実装
ドラムマシンの実装・ モジュレーションのお話・ beats の出力・ groove の実装※独断と偏見が強くなります
モジュレーションのお話・ 変調すること・ 時間的変化を与える
モジュレーションのお話・ 変調すること・ 時間的変化を与える どういうこと?
例)pulse 波形で変調する              時間の経過度合い +                                (t) -振幅    音程が   音程が   音程が   音程が   音程が      上がる   下...
例)音量を変化させる振幅              度合い                +          (t)               (t)                -                掛け合わせる     振...
キックの音度合い+                (t)-      変調振幅                    度合い                      +                (t)                  ...
キックの音my $kick = {   osc => {                    振幅    「変調前の波形」       freq => 20,       waveform => sin,                   ...
ハイハット / スネアの音サンプル&ホールドを使って変調する度合い+                       (t)-       元々は乱数を使ったノイズ+                       (t)-      一定期間、直前の...
スネアの音my $snare = {   osc => {                     振幅    「変調前の波形」       freq => 400,       waveform => tri,                ...
ハイハットの音# クローズハイハット(短い音)my $o_hat = {   osc => {       freq => 16000,       waveform => tri,       mod => { speed => 0.06, ...
beats の出力・ テンポ・ 発音パターン・ 音色・ 音量
beats の出力・ テンポ・ 発音パターン・ 音色    これを説明してきた・ 音量
beats の出力発音パターン# 0: 鳴らさない / 1: 鳴らすmy %patterns = (   kick => [ 1,0,0,0, 1,0,0,0,    1,0,0,0,   1,0,0,0   ],   snare => [ 0...
beats の出力テンポと音量my $synth = Sound::NeSynth->new();$synth->render({    bpm => 138, # beats per minute    beats => [         ...
groove の実装・ 音に強弱を付ける・ 音の長さに変化を付ける・ 音を鳴らすタイミングをずらす
groove の実装・ 音に強弱を付ける  → 音量だけ違うパートを増やす・ 音の長さに変化を付ける  → 音の長さだけ違うパートを増やす・ 音を鳴らすタイミングをずらす  → スウィングさせてみる!
groove の実装処理フロー1. 単音の波形を作る2. 発音タイミングの計算3. 波形をコピー4. ミキシング
groove の実装1. 単音の波形を作るmy $kick = {    osc => {        freq => 20,        waveform => sin,        mod => { speed => 0.35, de...
groove の実装2. 発音タイミングの計算# 0: 鳴らさない / 1: 鳴らすmy %patterns = (     kick   => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]);         ...
groove の実装3. 波形をコピー# 0: 鳴らさない / 1: 鳴らすmy %patterns = (     kick   => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]);発音タイミングがコピー開始...
groove の実装4. ミキシングfor (my $j=0; $j<scalar(@{$ch}); $j++) {   $samples[$j] += ( $ch->[$j] * $beats->[$i]->{vol} );}  こんな感じで...
groove の実装スウィングさせるには?1. 単音の波形を作る2. 発音タイミングの計算   ここ3. 波形をコピー4. ミキシング
groove の実装スウィングさせる# 0: 鳴らさない / 1: 鳴らすmy %patterns = (     kick    => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]);             ...
まとめ・ perl でも音楽ができる・ 楽器としては「きびしい」・ デジタル信号処理は楽しい
まとめ・ perl でも音楽ができる・ 楽器としては「きびしい」・ デジタル信号処理は楽しいもし、興味を持っていただけたなら・・・
続きは Web で!https://github.com/techno-cat/NeSynth/
ご清聴ありがとうございました。
Upcoming SlideShare
Loading in …5
×

perl meets beats.

2,429 views

Published on

YAPC::Asia Tokyo 2011 で20分枠を貰ってやった、「perl meets beats.」です。
perlでWAVEファイルを出力して、perlでドラムマシンを実装します。

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,429
On SlideShare
0
From Embeds
0
Number of Embeds
101
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

perl meets beats.

  1. 1. perl meets beats! 2011/10/14 @techno_neko
  2. 2. ちょっとその前に、マイクのテスト
  3. 3. ちょっとその前に、 マイクのテストこんな感じの音を出します。
  4. 4. 自己紹介所属:Hokkaido.pmTwitterID:@techno_neko職種:組み込み系
  5. 5. 今日のお題・ WAVE ファイルのお話・ ドラムマシンを作る・ デモンストレーション
  6. 6. 今日のお題・ WAVE ファイルのお話・ ドラムマシンを作る・ デモンストレーション perl で音楽をやります!
  7. 7. WAVE ファイルのお話・ ファイルフォーマット・ 音階のお話・ 音をファイルに書き出す
  8. 8. WAVE ファイルフォーマット こんな感じRIFF チャンク ヘッダー fmt チャンク フォーマット “data” data チャンク size 1 2 データ数 … 100 101 波形データ 102
  9. 9. WAVE ファイルの出力my $header = RIFF # chunkID 波形データ以外は、 . pack(L, ($size + 32)) # chunkSize . WAVE; # formTypemy $fmt_chunk = こんな感じで pack して、 fmt # chunkID . pack(L, 16) # chunkSize . pack(S, 1) # waveFormatType ファイル出力する . pack(S, 1) # channel . pack(L, $samples_per_sec) # samplesPerSec . pack(L, $block_size * $samples_per_sec) # bytesPerSec . pack(S, $block_size) # blockSize . pack(S, $bits_per_sample); # bitsPerSamplemy $data_chunk = data # chunkID . pack(L, $size); # chunkSize 波形データも同様に、 pack して出力する
  10. 10. 音階のお話・ ラの音は 440Hz・ 1 オクターブ違うと倍になる・ 平均律を採用
  11. 11. 音階のお話 Hz index 周波数 = 440 × 2880Hz440Hz220Hz index -1 0 1 ラ ラ ラ
  12. 12. 音階のお話 index/12 Hz 周波数 = 440 × 2880Hz440Hz この間を 12 等分する index -2 0 2 3 5 7 8 10 12 14 ソ ラ シ ド レ ミ ファ ソ ラ シ
  13. 13. 音階のお話 Hz my $freq = 440 * ( 2 ** ($index / 12) );880Hz440Hz この間を 12 等分する index -2 0 2 3 5 7 8 10 12 14 ソ ラ シ ド レ ミ ファ ソ ラ シ
  14. 14. 音をファイルに書き出す・ サンプリング周波数・ 量子化ビット数・ 音の長さ・ 音の周波数
  15. 15. 例)ラの音 (440Hz) サンプリング周波数 : 44,100Hz 量子化ビット数 : 16(-32768〜+32767) 音の長さ : 1 秒 44,100 / 440+32767 1 周期-32767 データの長さ = サンプリング周波数 × 音の長さ
  16. 16. ドラムマシンの実装・ モジュレーションのお話・ beats の出力・ groove の実装
  17. 17. ドラムマシンの実装・ モジュレーションのお話・ beats の出力・ groove の実装※独断と偏見が強くなります
  18. 18. モジュレーションのお話・ 変調すること・ 時間的変化を与える
  19. 19. モジュレーションのお話・ 変調すること・ 時間的変化を与える どういうこと?
  20. 20. 例)pulse 波形で変調する 時間の経過度合い + (t) -振幅 音程が 音程が 音程が 音程が 音程が 上がる 下がる 上がる 下がる 上がる (t)
  21. 21. 例)音量を変化させる振幅 度合い + (t) (t) - 掛け合わせる 振幅 (t) 時間の経過
  22. 22. キックの音度合い+ (t)- 変調振幅 度合い + (t) (t) - 掛け合わせる 振幅 (t)
  23. 23. キックの音my $kick = { osc => { 振幅 「変調前の波形」 freq => 20, waveform => sin, (t) mod => { speed => 0.35, depth => 3.5, 度合い 「周波数の時間的変化」 waveform => env, + curve => 1.6 (t) } - }, amp => { 度合い 「音量の時間的変化」 sec => 0.25, + waveform => env, curve => 1.4 (t) } -};
  24. 24. ハイハット / スネアの音サンプル&ホールドを使って変調する度合い+ (t)- 元々は乱数を使ったノイズ+ (t)- 一定期間、直前の値を保持する
  25. 25. スネアの音my $snare = { osc => { 振幅 「変調前の波形」 freq => 400, waveform => tri, (t) mod => { speed => 0.10, depth => 9.0, 度合い 「周波数の時間的変化」 waveform => noise + } (t) }, - amp => { sec => 0.18, 度合い 「音量の時間的変化」 waveform => env, + curve => 2.2 } (t)}; -
  26. 26. ハイハットの音# クローズハイハット(短い音)my $o_hat = { osc => { freq => 16000, waveform => tri, mod => { speed => 0.06, depth => 6.0, waveform => noise } }, amp => { sec => 0.2, waveform => env, curve => 2.7 }};# オープンハイハット(長い音)my $c_hat = { osc => { freq => 16000, waveform => tri, mod => { speed => 0.06, depth => 6.0, waveform => noise } }, amp => { sec => 0.15, waveform => env, curve => 2.7 }};
  27. 27. beats の出力・ テンポ・ 発音パターン・ 音色・ 音量
  28. 28. beats の出力・ テンポ・ 発音パターン・ 音色 これを説明してきた・ 音量
  29. 29. beats の出力発音パターン# 0: 鳴らさない / 1: 鳴らすmy %patterns = ( kick => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ], snare => [ 0,0,0,0, 1,0,0,0, 0,0,0,0, 1,0,0,0 ], o_hat => [ 0,0,1,0, 0,0,1,0, 0,0,1,0, 0,0,1,0 ], c_hat => [ 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1 ]); 16 個で 1 小節分
  30. 30. beats の出力テンポと音量my $synth = Sound::NeSynth->new();$synth->render({ bpm => 138, # beats per minute beats => [ 音量の設定 { seq => $patterns{kick}, tone => $kick, vol => 1.00 }, { seq => $patterns{snare}, tone => $snare, vol => 0.12 }, { seq => $patterns{o_hat}, tone => $o_hat, vol => 0.06 }, { seq => $patterns{c_hat}, tone => $c_hat, vol => 0.015 } ]});# ファイル出力$synth->write( "techno.wav" );
  31. 31. groove の実装・ 音に強弱を付ける・ 音の長さに変化を付ける・ 音を鳴らすタイミングをずらす
  32. 32. groove の実装・ 音に強弱を付ける → 音量だけ違うパートを増やす・ 音の長さに変化を付ける → 音の長さだけ違うパートを増やす・ 音を鳴らすタイミングをずらす → スウィングさせてみる!
  33. 33. groove の実装処理フロー1. 単音の波形を作る2. 発音タイミングの計算3. 波形をコピー4. ミキシング
  34. 34. groove の実装1. 単音の波形を作るmy $kick = { osc => { freq => 20, waveform => sin, mod => { speed => 0.35, depth => 3.5, waveform => env, curve => 1.6 } }, amp => { sec => 0.25, waveform => env, curve => 1.4 }};+1.0 -1.0 から +1.0 が格納された配列-1.0 配列のサイズ = 44,100 * 0.25 0.25 sec
  35. 35. groove の実装2. 発音タイミングの計算# 0: 鳴らさない / 1: 鳴らすmy %patterns = ( kick => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]); index テンポに合わせて 4 分音符を配置するための間隔 間隔 = サンプリング周波数 / テンポ( beats per sec ) 今回はさらに 4 で割った値で計算している
  36. 36. groove の実装3. 波形をコピー# 0: 鳴らさない / 1: 鳴らすmy %patterns = ( kick => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]);発音タイミングがコピー開始時のオフセット
  37. 37. groove の実装4. ミキシングfor (my $j=0; $j<scalar(@{$ch}); $j++) { $samples[$j] += ( $ch->[$j] * $beats->[$i]->{vol} );} こんな感じで、1 つの配列に足し込む
  38. 38. groove の実装スウィングさせるには?1. 単音の波形を作る2. 発音タイミングの計算 ここ3. 波形をコピー4. ミキシング
  39. 39. groove の実装スウィングさせる# 0: 鳴らさない / 1: 鳴らすmy %patterns = ( kick => [ 1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0 ]); index index 0 1 2 3 4 5 6 7 8 9 10 11 12 index が奇数の場合、発音タイミングをずらすことで実現
  40. 40. まとめ・ perl でも音楽ができる・ 楽器としては「きびしい」・ デジタル信号処理は楽しい
  41. 41. まとめ・ perl でも音楽ができる・ 楽器としては「きびしい」・ デジタル信号処理は楽しいもし、興味を持っていただけたなら・・・
  42. 42. 続きは Web で!https://github.com/techno-cat/NeSynth/
  43. 43. ご清聴ありがとうございました。

×