Suara Kata-kata

11

Orang telah menulis banyak hal yang memungkinkan satu hal divisualisasikan sebagai hal lain. Sekarang saya mengusulkan untuk dapat menerjemahkan surat ke musik! Tugas Anda untuk menulis sebuah program yang mengambil file teks dan menghasilkan file suara dengan setiap huruf dikonversi ke catatan tertentu C3-C8.

Penafian - Saya sebenarnya tidak berharap musik terdengar bagus tapi saya berharap akan terkejut.

Spesifikasi

  • Anda mengambil nama file sebagai string dan BPM (denyut per menit) sebagai int
  • Anda membuat huruf besar Amenjadi catatanC3
  • Dan naik setengah langkah untuk setiap karakter setelah dalam urutan ini: ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
  • Ya, tidak setiap karakter akan digunakan karena rentang oktafnya terlalu banyak.
  • Anda menerjemahkan setiap karakter dalam file dengan cara ini
  • Letakkan not bersama di BPM yang diberikan sebagai not seperempat
  • Baik menyimpan sebagai file suara (saya kira midi akan menjadi yang termudah, tetapi semuanya baik-baik saja) atau mainkan
  • Setiap format input yang waras baik-baik saja
  • Tidak ada celah standar
  • Ini adalah kode-golf, jadi kode terpendek dalam byte menang!

Bonus

  • Izinkan transposing output - 50 byte
  • Izinkan beberapa trek ditumpangkan satu sama lain dengan mengambil beberapa file - 75 byte
  • Gabung huruf berturut-turut menjadi satu catatan lagi - 50 byte

Sunting: Wow, kami memiliki skor negatif. Saya akan mengumumkan pemenang pada hari Sabtu.

Maltysen
sumber
Kapan Anda akan memutuskan pemenang?
LegionMammal978
Bisakah kita berasumsi bahwa input tidak akan mengandung karakter yang tidak terdaftar? Atau, apa yang harus kita lakukan ketika menemukan karakter yang tidak terdaftar?
apsillers
@apsillers In the Snap ! menjawab, dia mengatakan bahwa dia akan mengizinkan perilaku yang tidak terdefinisi.
LegionMammal978
Saya mengunggah sampel; Anda cukup benar, itu benar-benar tidak terdengar baik setiap ...
Sanchises

Jawaban:

6

MATLAB, 159-50-50-75 = -16

Input sampel

Output sampel

Menghasilkan gelombang suara sinus murni, sangat funky (gigi gergaji juga dimungkinkan, dengan skor yang lebih baik, tapi itu terdengar agak ... terlalu funky). Berfungsi sebagai fungsi, jadi harapkan itu array karakter ( ['abc';'def']) dengan satu baris per 'lagu'. Saya pikir itu tercakup dalam 'format input yang waras' , tetapi jika konsensus umum adalah bahwa saya perlu membaca file, saya kira saya dapat mengubahnya. Input iadalah trek teks (dengan panjang yang sama), bdenyut per menit dan ttranspos (pasokan 0 untuk tidak ditransposisikan). Ini memadukan dua sinus menjadi satu dengan mengimbangi input sinus, jadi saya mendapat ketiga bonus, memberi saya skor negatif.

function v(i,b,t)
s=0;for r=1:size(i)
o=[];for k=i(r,:)
o=cat(2,o,sin(55*pi*2^((k-28+t)/12)*(numel(o)/2^13+(0:1/2^13:60/b))));end
s=s+o;end
sound(s/max(s))
end

Versi menggunakan file input: 211-175 = 36

Argumen input isekarang mewakili nama file, parameter lainnya tidak berubah. Mungkin tidak berfungsi pada rilis yang lebih baru karena saya mendapatkan peringatan yang textreadmungkin akan segera usang. EDIT: textread tampaknya secara otomatis terpecah di spasi putih, jadi saya memperbaikinya. Juga, saya pikir saya mungkin secara tidak sengaja menghubungi beberapa alien dengan suara aneh yang dibuat saat pengujian.

function v(i,b,t)
i=textread(i,'%s','whitespace','','delimiter','\n');s=0;for r=1:size(i)
o=[];for k=i{r,:}
o=cat(2,o,sin(55*pi*2^((k-28+t)/12)*(numel(o)/2^13+(0:1/2^13:60/b))));end
s=s+o;end
sound(s/max(s))
end

Versi mana yang Anda sukai? :)

Sanchises
sumber
Nah, spec mengatakan secara eksplisit untuk mengambil input dari file ...
LegionMammal978
@ LegionMammal978 Jika Anda bersikeras: .matfile adalah format input yang waras. Buat file .mat dengan variabel 'i' yang memiliki teks Anda. Kemudian, tambahkan load(i);di awal baris 2 dari versi teratas. Nilai: -16 + 8 = -8. Saya akan melakukan ini ketika komentar Anda mendapat lebih banyak suara daripada komentar saya, atau ketika OP memiliki pendapat :)
Sanchises
4

Jepret ! - 401 - 75 = 326

Cobalah online di sini.

Saya menggunakan metode ini menghitung byte untuk program ini.

masukkan deskripsi gambar di sini

Saya menambahkan memainkan beberapa suara sekaligus.

Struktur dasarnya sama dengan aslinya (lihat di bawah), tetapi dengan penambahan launch{}. launch{}memulai utas baru dengan kode di dalamnya, memungkinkan untuk konkurensi.

Kode sebagai teks:

set[c v]to[ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
set[l v]to(list>
ask[BPM]and wait
set tempo to(answer)bpm
repeat until<(answer)=[
ask[notes]and wait
add(answer)to(l
end
delete(last v)of(l
for each(i)of(l
launch{
repeat(length of(i))(#
play note(i(c)(letter(#)of(i)))for(0.25)beats

(i(h)(n))
report(call(JavaScript function ([h][n]) {[return h.indexOf(n)+48]})with inputs(h)(n

Kode asli, 308.

masukkan deskripsi gambar di sini

Lucky Snap! memiliki MIDI bermain bawaan.;)

Sayangnya, itu tidak memiliki indexOffungsi, jadi saya harus membuat panggilan JavaScript eksternal, yang cukup mahal.

The repeat () (#)blok berasal dari perpustakaan iterasi.

Kode ini dapat ditulis sebagai teks seperti ini, yang merupakan cara saya mendapatkan 308 byte:

set[c v]to[ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
ask[BPM]and wait
set tempo to(answer)bpm
ask[notes]and wait
repeat(length of(answer))(#)
play note(i(c)(letter(#)of(answer)))for(0.25)beats

(i(h)(n))
report(call(JavaScript function ([h][n]) {[return h.indexOf(n)+48]})with inputs(h)(n
Scimonster
sumber
Apakah SNAP memiliki koleksi / showcase yang dapat Anda tambahkan seperti Scratch? Menautkan langsung ke versi yang bisa dijalankan akan menjadi IMO yang praktis.
Geobits
Iya. Saya menambahkan tautan ke proyek saya. Ide bagus. :)
Scimonster
Apakah itu mengabaikan -1dari indexOf? Saat ini sepertinya tidak ada dalam string, itu tidak midi nomor 47.
Maltysen
@Maltysen Pertanyaannya tidak pernah mengatakan apa yang harus dilakukan dengan input di luar kisaran yang tepat.
Scimonster
Benar. Saya bermaksud agar hal itu diabaikan tetapi karena saya rasa ini adalah kesalahan saya karena tidak cukup spesifik, saya akan mengizinkannya.
Maltysen
4

Mathematica, 219 - 50 - 75 - 50 = 44

c=CharacterRange;d=Import;EmitSound[Function[b,Sound[Split@Characters@d@b/.a:{__String}:>SoundNote[StringPosition[c["A","Z"]<>" ()-,;.'\""<>c["a","z"],a[[1]]][[1,1]]+#3-12,60Length@a/#2],{0,60StringLength@d@b/#2}]]/@#]&

Mengambil daftar file input, BPM, dan jumlah setengah langkah untuk ditransposisikan sebagai input dan memainkan suara (dari piano, instrumen lain akan membutuhkan lebih banyak byte.) Tidak terdengar terlalu buruk!

LegionMammal978
sumber
1

JavaScript (ES6) 377 - 50 - 50 - 75 = 202

Pertama, inilah cuplikan runnable yang menggunakan <input>bidang alih-alih membaca file:

<b>BMP:</b> <input id="bpm" size=3 placeholder="BMP" value="120"> <b>Transpose:</b> <input size=3 id="transpose" placeholder="Transpose" value="0"><br/><br/><div id="tracks" style="float:left;padding-right:5px;"><input placeholder="Track" class="track"></div><button id="add">Add Additional Track</button><div style="clear:both; padding-top:5px;"></div><button id="play"><b>Play</b></button><script>f=function(s,b,z){C=new (window.AudioContext||window.webkitAudioContext);b=6e4/b;s.map(function(p){var o=C.createOscillator(t=setTimeout);o.connect(C.destination);o.start();p.split("").map(function(c,i){t(function(){o.frequency.value=440*Math.pow(2, ("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12)},b*i)});t(function(){o.stop()},p.length*b)})};document.getElementById("play").onclick=function(){f([].map.call(document.getElementsByClassName("track"),function(e){return e.value;}),+document.getElementById("bpm").value,+document.getElementById("transpose").value);};document.getElementById("add").onclick=function(){var i=document.createElement("input");i.placeholder="Track";i.className="track";document.getElementById("tracks").appendChild(document.createElement("br"));document.getElementById("tracks").appendChild(i);};</script>

Dan sekarang, entri yang sebenarnya:

f=(n,b,z)=>{C=new AudioContext;b=6e4/b;s=n.map(m=>(x=new XMLHttpRequest,x.open("GET",m,0),x.send(),x.responseText));s.map(p=>{var o=C.createOscillator(t=setTimeout);o.connect(C.destination);o.start();[...p].map((c,i)=>t(_=>o.frequency.value=440*Math.pow(2,("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12),b*i)),t(_=>o.stop(),p.length*b)})}

Tiga argumen adalah array string filepath untuk dimainkan secara bersamaan, catatan per menit, dan jumlah setengah langkah untuk mengubah semua input.

Dengan spasi dan komentar:

f=(n,b,z)=>{
    C=new AudioContext;
    b=6e4/b;

    // fill s with the contents of each file
    s = n.map(m=>(x=new XMLHttpRequest,x.open("GET",m,0),x.send(),x.responseText));

    // play each track
    s.map(p=>{
        var o=C.createOscillator(t=setTimeout);
        o.connect(C.destination);
        o.start();

        // queue up each note with setTimeout
        [...p].map((c,i)=>
            t(_=>
                o.frequency.value=440*
                    Math.pow(2,
                            ("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12
                    ),
             b*i)
        );
        // queue up termination of those track
        t(_=>o.stop(),p.length*b)})
}

f(["file:///home/users/apsillers/notes.txt",
   "file:///home/users/apsillers/notes2.txt"],
  240, 5)
apsillers
sumber