Звук слов

11

Люди написали много вещей, позволяющих визуализировать одну вещь как другую. Теперь я предлагаю возможность переводить буквы на музыку! Ваша задача - написать программу, которая берет текстовый файл и выводит звуковой файл, в котором каждая буква преобразуется в конкретную заметку C3-C8.

Отказ от ответственности - я не ожидаю, что музыка будет звучать хорошо, но я надеюсь удивиться.

Характеристики

  • Вы берете имя файла в виде строки, а BPM (ударов в минуту) как int
  • Вы делаете прописные Aбыть примечаниеC3
  • И поднимитесь на полшага для каждого персонажа после в следующем порядке: ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
  • Да, не каждый символ будет использоваться, поскольку он охватывает слишком много октав.
  • Вы переводите каждый символ в файле таким образом
  • Положите заметки вместе в данном BPM как квартальные заметки
  • Либо сохраните как звуковой файл (я думаю, что midi будет самым простым, но все в порядке), либо воспроизведите его
  • Любой вменяемый формат ввода в порядке
  • Нет стандартных лазеек
  • Это код-гольф, поэтому выигрывает самый короткий код в байтах !

Бонусы

  • Разрешить транспонирование вывода - 50 байтов
  • Позволяет накладывать несколько дорожек друг на друга, принимая несколько файлов - 75 байт
  • Соедините последовательные буквы в одну более длинную ноту - 50 байтов

Изменить: Ух, у нас отрицательные оценки. Я объявлю победителя в субботу.

Maltysen
источник
Когда вы будете определять победителя?
LegionMammal978
Можем ли мы предположить, что ввод не будет содержать каких-либо не перечисленных символов? Или, что мы должны делать, когда мы встретили незарегистрированных персонажей?
Апсиллеры
@apsillers в оснастке ! Отвечая, он сказал, что допустит неопределенное поведение.
LegionMammal978
Я загрузил образец; Вы были совершенно правы, это действительно звучит не очень хорошо ...
Sanchises

Ответы:

6

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

Пример ввода

Образец вывода

Генерирует чистые синусоидальные звуковые волны, очень прикольные (пилообразный также возможен, с еще лучшим счетом, но это звучит немного ... слишком прикольно). Работает как функция, поэтому ожидает, что это массив символов ( ['abc';'def']) с одной строкой на каждый трек. Я думаю, что это подпадает под «любой нормальный формат ввода» , но если общее мнение заключается в том, что мне нужно прочитать файл, я думаю, что я могу изменить его. Ввод i- это текстовые дорожки (одинаковой длины), bударов в минуту и tтранспонирования (подача 0 для не транспонированных). Он смешивает два синуса в один, компенсируя вход синуса, поэтому я получил все три бонуса, что дало мне отрицательный результат.

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

Версия с использованием входного файла: 211-175 = 36

Входной аргумент iтеперь представляет имя файла, остальные параметры без изменений. Может не работать на более новых выпусках, потому что я получаю предупреждение, которое textreadскоро может быть объявлено устаревшим. РЕДАКТИРОВАТЬ: текстовое чтение, очевидно, автоматически распадается на пробелы, поэтому я исправил это. Кроме того, я думаю, что мог случайно связать некоторых пришельцев со странными звуками, издаваемыми во время тестирования.

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

Какую версию вы предпочитаете? :)

Sanchises
источник
Ну, спецификация явно говорит, чтобы взять входные данные из файла ...
LegionMammal978
@ LegionMammal978 Если вы настаиваете: .matфайлы имеют нормальный формат ввода. Создайте файл .mat с переменной 'i', содержащей ваш текст. Затем добавьте load(i);в начале строки 2 верхней версии. Оценка: -16 + 8 = -8. Я сделаю это, когда ваш комментарий получит больше голосов, чем мой, или когда у ОП есть мнение :)
Sanchises
4

Snap ! - 401 - 75 = 326

Попробуйте это онлайн здесь.

Я использую этот метод подсчета байтов для программы.

введите описание изображения здесь

Я добавил воспроизведение нескольких звуков одновременно.

Базовая структура такая же, как и в оригинале (см. Ниже), но с добавлением launch{}. launch{}запускает новый поток с кодом внутри, учитывая параллелизм.

Код в виде текста:

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

Оригинальный код, 308.

введите описание изображения здесь

Счастливчик! есть встроенная игра MIDI.;)

К сожалению, у него нет indexOfфункции, поэтому мне нужно сделать внешний вызов JavaScript, что довольно дорого.

repeat () (#)Блок поставляется из библиотеки итераций.

Код можно записать в виде текста, вот так я получаю 308 байт:

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
источник
Есть ли у SNAP коллекция / витрина, в которую вы можете добавить их, как в Scratch? Прямая ссылка на работоспособную версию была бы удобной IMO.
Geobits
Да. Я добавил ссылку на свой проект. Хорошая идея. :)
Scimonster
Это игнорирует -1от indexOf? Прямо сейчас это выглядит, как будто его нет в строке, он делает миди номер 47.
Maltysen
@Maltysen Вопрос никогда не говорит о том, что делать с входом за пределы допустимого диапазона.
Scimonster
Правда. Я хотел, чтобы это было проигнорировано, но, поскольку я предполагаю, что это моя вина, что я недостаточно конкретен, я позволю это.
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}]]/@#]&

Принимает список входных файлов, BPM и количество полушагов для транспонирования в качестве входных данных и воспроизводит звук (от пианино любой другой инструмент занял бы больше байтов.) Звучит неплохо!

LegionMammal978
источник
1

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

Во-первых, вот исполняемый фрагмент, который использует <input>поля вместо чтения файла:

<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>

А теперь актуальная запись:

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)})}

Три аргумента представляют собой массив строк filepath для одновременного воспроизведения, количество нот в минуту и ​​количество полушагов для транспонирования всех входных данных.

С пробелами и комментариями:

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
источник