ステートメント
タスクは、(お好みの)汎用プログラミング言語の機能を使用して、(お好みの)楽器の音(1つのノートを演奏)を合成することです。
2つの目標があります。
- 結果として生じる音の品質。実際の楽器にできるだけ似ている必要があります。
- 最小限。コードを1500バイト未満に維持することをお勧めします(基本的なサウンド生成のみがある場合はそれよりも少なくなります)。
生成関数のみを提供する必要があり、定型句はスコアにカウントされません。
残念ながら、音の忠実度についてスコアを計算することはできないため、厳密な規則はありません。
ルール:
- サンプルライブラリ、特殊な音楽生成物に依存しません。
- ネットワークからダウンロードしたり、マイクやオーディオカードのMIDIなど、外部のようなものを使用したりすることはありません。
- コードサイズの測定単位はバイトです。ファイルは現在のディレクトリに作成できます。既存のファイル(係数テーブルなど)が存在する場合がありますが、そのコンテンツはスコアに追加され、名前で開く必要があります。
- ボイラープレートコード(スコアにカウントされない)は、符号付き整数の配列(リスト)を受け取り、出力のみを処理します。
- 出力形式は、オプションのWAVヘッダーを使用して、1秒あたり44100サンプルのリトルエンディアン16ビットワードで署名されています。プレーンなwavの代わりに圧縮されたオーディオを出力しようとしません。
- 合成するために別の楽器を選択してください(または楽器のその他の品質とコードサイズのカテゴリ)。ただし、最初は何をシミュレートしているかを教えてはいけません。他のユーザーにコメントで推測させてください。
- 電子機器は使用しないでください。
- ドラムは楽器です。人間の声は楽器です。
ボイラープレート
一部の言語の定型文を次に示します。あなたの言語にも同様の定型文を書くことができます。「g」関数は、デモ用です(1秒440 Hzのサイントーン)。
C:
//#!/usr/bin/tcc -run
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
/*
void g(signed short *array, int* length) {
*length = 44100;
int i;
for(i=0; i<44100; ++i) array[i]=10000*sin(i*2.0*3.14159265358979323*440.0/44100.0);
}
*/
// define your g here
signed short array[44100*100];
int main(int argc, char* argv[]) {
int size=0;
memset(array,0,sizeof array);
// i(array); // you may uncomment and implement some initialization
g(array, &size);
fwrite("RIFFH\x00\x00\x00WAVEfmt\x20\x12\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00\x00\x00LIST\x1a\x00\x00\x00INFOISFT\x0e\x00\x00\x00GolfNote\0\0\0\0\0\0data\x00\xff\xff\xff", 1, 80, stdout);
fwrite(array, 1, size*sizeof(signed short), stdout);
return 0;
}
Python 2:
#!/usr/bin/env python
import os
import re
import sys
import math
import struct
import array
#def g():
# return [int(10000*math.sin(1.0*i*2*3.141592654*440.0/44100.0)) for i in xrange(0,44100)]
# define your g here
sys.stdout.write("RIFFH\x00\x00\x00WAVEfmt\x20\x12\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00\x00\x00LIST\x1a\x00\x00\x00INFOISFT\x0e\x00\x00\x00GolfNotePy\0\0\0\0data\x00\xff\xff\xff");
array.array("h", g()).tofile(sys.stdout);
Perl 5:
#!/usr/bin/perl
#sub g() {
# return (map 10000*sin($_*3.14159265358979*2*440.0/44100.0), 0..(44100-1))
#}
# define you g here
my @a = g();
print "RIFFH\x00\x00\x00WAVEfmt\x20\x12\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00\x00\x00LIST\x1a\x00\x00\x00INFOISFT\x0e\x00\x00\x00GolfNotePl\0\0\0\0data\x00\xff\xff\xff";
print join("",map(pack("s", $_), @a));
ハスケル:
#!/usr/bin/runhaskell
import qualified Data.Serialize.Put as P
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C8
import Data.Word
import Control.Monad
-- g :: [Word16]
-- g = map (\t->floor $ 10000 * sin(t*2*3.14159265358979*440/44100)) [0..44100-1]
-- insert your g here
main = do
B.putStr $ C8.pack $ "RIFFH\x00\x00\x00WAVEfmt\x20\x12\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00\x00\x00LIST\x1a\x00\x00\0INFOISFT\x0e\x00\x00\x00GolfNote\0\0\0\0\0\0data\x00\xff\xff\xff"
B.putStr $ P.runPut $ sequence_ $ map P.putWord16le g
例
これはピアノの音をモデルにしたC版です。
void g(signed short *array, int* length) {
*length = 44100*5;
int i;
double overtones[]={4, 1, 0.5, 0.25, 0.125};
double freq[] = {393, 416, 376, 355, 339, 451, 555};
double freq_k[] = {40, 0.8, 1, 0.8, 0.7, 0.4, 0.25};
double corrector = 1/44100.0*2*3.14159265358979323;
double volumes_begin[] ={0, 0.025, 0.05, 0.4};
double volumes_end [] ={0.025, 0.05, 0.4, 5};
double volumes_kbegin[]={0, 1.8, 1, 0.4};
double volumes_kend [] ={1.8, 1, 0.4, 0};
for(i=0; i<44100*5; ++i) {
int j;
double volume = 0;
for(j=0; j<sizeof volumes_begin/sizeof(*volumes_begin); ++j) {
double t = i/44100.0;
if(t>=volumes_begin[j] && t<volumes_end[j]) {
volume += volumes_kbegin[j]*(volumes_end[j]-t )/(volumes_end[j]-volumes_begin[j]);
volume += volumes_kend[j] *(t-volumes_begin[j])/(volumes_end[j]-volumes_begin[j]);
}
}
int u;
for(u=0; u<sizeof freq/sizeof(*freq); ++u) {
for(j=0; j<sizeof overtones/sizeof(*overtones); ++j) {
double f = freq[u]*(j+1);
array[i] += freq_k[u]*volume*10000.0/(f)/1*overtones[j]*sin(1.0*i*corrector*f);
}
}
}
}
スコアは約1330バイトであり、品質は中程度です。
q
のようになります。pastebin.com/ZCB1v7QQ。ホストはビッグエンディアンですか?
$><<7.chr
Rubyの数に?:9文字のP!または$><<?\a
7文字の場合