Beyan
Görev, bazı genel amaçlı programlama dillerinde (seçtiğiniz) fonksiyonu kullanarak bazı müzik aletlerinin sesini (seçtiğiniz bir nota) sentezlemektir.
İki hedef var:
- Ortaya çıkan ses kalitesi. Gerçek enstrümana mümkün olduğunca iyi benzemelidir;
- Minimality. Kodun 1500 baytın altında tutulması önerilir (yalnızca temel ses üretimi varsa daha az).
Sadece üretim fonksiyonunun sağlanması gerekir, kazan için plaka sayılmaz.
Ne yazık ki, ses sadakati için hiçbir puan hesaplanamaz, bu nedenle katı kurallar olamaz.
Kurallar:
- Örnek kütüphanelere bağımlılık yok, özel müzik üretimi şeyler;
- Ağdan indirme veya mikrofon veya ses kartının MIDI'sini veya bunun gibi çok harici bir şeyi kullanmaya çalışmak yok;
- Kod boyutu ölçüm birimi bayttır. Geçerli dizinde dosya oluşturulabilir. Önceden var olan dosyalar (katsayı tabloları, vb.) Bulunabilir, ancak içerikleri skora eklenir + adıyla açmaları gerekir.
- Ortak kod (puan sayılmaz) imzalı tamsayıların dizisini (listesini) alır ve yalnızca bunların çıktısını alır.
- Çıktı biçimi, isteğe bağlı WAV üstbilgisi ile küçük endian 16 bit sözcükler, saniyede 44100 örnek imzalanır. Düz wav yerine sıkıştırılmış ses çıkarmaya çalışmak yok;
- Lütfen sentezlemek için farklı enstrümanlar seçin (veya enstrüman için başka bir kalite ve kod boyutu kategorisi); ancak başlangıçta neyi simüle ettiğinizi söylemeyin - diğer kullanıcıların yorumlarda tahmin yapmasına izin verin;
- Elektronik aletler önerilmez;
- Davul bir araçtır. İnsan sesi bir araçtır.
BoilerPlates
İşte bazı diller için ısıtıcı plakalar. Diliniz için de benzer bir kazan plakası yazabilirsiniz. Yorumlanan "g" işlevi sadece bir demo içindir (1 saniye 440 Hz sinüs tonu).
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));
Haskell:
#!/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
Misal
İşte piyano sesinden sonra modellenmemiş ungolfed C versiyonu:
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);
}
}
}
}
Yaklaşık 1330 bayt alır ve kötü / vasat kalite sağlar.
q
şöyle görünmelidir: pastebin.com/ZCB1v7QQ . Ev sahibi big-endian mı?
$><<7.chr
Ruby sayısında? : 9 karakter için P! veya $><<?\a
7 karakter için