Pernyataan
Tugasnya adalah untuk mensintesis suara (satu nada dimainkan) dari beberapa alat musik (pilihan Anda) menggunakan fungsi dalam beberapa bahasa pemrograman tujuan umum (pilihan Anda).
Ada dua tujuan:
- Kualitas suara yang dihasilkan. Itu harus menyerupai instrumen nyata sehalus mungkin;
- Minimalitas Menyimpan kode di bawah 1500 byte disarankan (kurang jika hanya ada generasi suara dasar).
Hanya fungsi pembangkitan yang perlu disediakan, boilerplate tidak dihitung untuk skor.
Sayangnya tidak ada skor yang dapat dihitung untuk kesetiaan suara, sehingga tidak ada aturan yang ketat.
Aturan:
- Tidak ada ketergantungan pada perpustakaan sampel, hal-hal generasi musik khusus;
- Tidak mengunduh dari jaringan atau mencoba menggunakan MIDI mikrofon atau kartu audio atau sesuatu yang terlalu eksternal seperti ini;
- Unit ukuran ukuran kode adalah byte. File dapat dibuat di direktori saat ini. File yang sudah ada sebelumnya (tabel koefisien, dll) mungkin ada, tetapi konten mereka ditambahkan ke skor + mereka harus dibuka dengan nama.
- Kode boilerplate (tidak dihitung untuk skor) menerima array (daftar) dari bilangan bulat yang ditandatangani dan hanya berurusan dengan mengeluarkannya.
- Format output ditandatangani sedikit kata-kata endian 16-bit, 44100 sampel per detik, dengan header WAV opsional. Tidak mencoba untuk mengeluarkan audio terkompresi, bukan wav biasa;
- Silakan pilih instrumen yang berbeda untuk disintesis (atau kategori ukuran kode vs kualitas lainnya untuk instrumen); tetapi pada awalnya jangan memberi tahu apa yang Anda simulasi - biarkan pengguna lain menebak dalam komentar;
- Instrumen elektronik tidak disarankan;
- Drum adalah instrumen. Suara manusia adalah instrumen.
Pelat boiler
Berikut adalah beberapa pelat untuk beberapa bahasa. Anda dapat menulis pelat ketel yang serupa untuk bahasa Anda juga. Mengomentari fungsi "g" hanya untuk demo (1 detik 440 Hz nada sinus).
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
Contoh
Inilah versi C ungolfed yang dimodelkan setelah suara piano:
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);
}
}
}
}
Skornya sekitar 1330 byte dan memberikan kualitas buruk / biasa-biasa saja.
q
akan terlihat seperti ini: pastebin.com/ZCB1v7QQ . Apakah tuan rumah Anda big-endian?
$><<7.chr
dalam Ruby dihitung? : P untuk 9 karakter! atau $><<?\a
untuk 7 karakter