Морс Новый год


33

Это еженедельный вызов № 1. Тема: Обработка аудио

Ваша задача - написать программу, которая записывает аудиофайл на диск (в формате по вашему выбору), который содержит код Морзе для 2015, т.е.

..--- ----- .---- .....

Вы можете выбрать любой тип звука для сегментов, например, одночастотную синусоидальную волну, аккорд, шум, какой-либо инструмент (например, с помощью файлов MIDI), если он слышен. Однако есть некоторые ограничения по срокам:

  • Короткие сегменты должны быть длиной не менее 0,2 секунды.
  • Длинные сегменты должны быть как минимум в 3 раза длиннее коротких.
  • Разрывы между сегментами в пределах цифры должны быть такой же длины, что и короткие сегменты.
  • Разрывы между цифрами должны быть такой же длины, как и длинные сегменты.
  • Каждый сегмент и разрыв могут отклоняться до 10% от средней длины сегмента / разбиения этого типа.
  • Весь аудиофайл не может быть длиннее 30 секунд.

Перерывы не должны быть абсолютно бесшумными, но сегменты Морзе должны быть слышно громче, чем разрывы.

Обратите внимание, что вы должны написать аудио файл. Вы не можете просто воспроизвести звук, например, используя системные гудки. Вы можете использовать любую библиотеку для обработки формата файла и генерации аудио, но вы не должны использовать встроенные функции для кодирования Морзе.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

Пожалуйста, рассмотрите возможность ссылки на загрузку полученного аудиофайла (в SoundCloud или аналогичной), чтобы люди могли проверить результат без необходимости запуска вашего кода. Если вы загружаете в SoundCloud, убедитесь, что вы включили загрузку на вкладке Permissions трека.

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

Пример трека

Это пример сгенерированного вручную трека, который соответствует спецификации и использует шум для сегментов Морзе (точнее, фоновый шум микрофона). Вот ссылка на SoundCloud, если у вас не работает встроенный проигрыватель.

Баунти Детали

Я назначу награду за самую короткую заявку на языке звукового программирования , то есть на языке, предназначенном для синтеза звука. Этот список не полный, поэтому не стесняйтесь использовать другой язык звукового программирования, если вы его знаете. Если вы не уверены, что какой-либо язык, который вы хотите использовать, классифицируется как язык звукового программирования, пожалуйста, дайте мне знать в комментариях или в чате , и мы можем обсудить это.

Обратите внимание, что ваша заявка по-прежнему должна соответствовать всем правилам - в частности, она должна написать файл, что может быть невозможно на всех языках звукового программирования. Например, насколько я могу судить, гиббер может только воспроизводить звук, а не сохранять его в файл.


1
Дополнительный вызов: Сделайте так, чтобы это звучало действительно хорошо.
Каз Вулф

6
@ Мью Как хорошо может звучать Морс?
Мартин Эндер

1
Выполнение этого в Brainf ** k сделало бы это потрясающим на многих бонусных уровнях.
Мачта

@Mast Возможно, но, к сожалению, BF не может записать в файл. ;) (Я постараюсь быть более снисходительным с этим в следующий раз.)
Мартин Эндер

Являются ли музыкальные форматы записи, содержащие только партитуры и не содержащие аудио (.mid, .abc, показанные ниже), признанными приемлемыми в качестве «аудиофайла»? А как насчет форматов «трекера», которые содержат как сэмплы, так и партитуры, но не воспроизводят звуковую дорожку (.mod, .xm)?
Tobia

Ответы:


4

AWK BASH: 66 86 67 74 байта

По просьбе Мартина Бюттнера я добавил темп, поскольку после проверки стандарта нотации ABC кажется, что для этого нет определенного значения по умолчанию (спасибо Nutki за указание этого).
Я также записываю в файл на диске (а) вместо STDOUT, так как вопрос явно хотел "файл на диске".

a=C3z;echo "X:1
K:A
Q:99
CzCz$a$a$a3$a$a$a$a${a}3Cz$a$a$a${a}3CzCzCzCzC">a

Я установил темп 99, который заставляет аудио файл длиться 22 секунды; Это медленнее, чем моя предыдущая версия, но, по крайней мере, теперь она должна быть одинаковой длины на каждом ABC-плеере, и она подходит менее 30 секунд.

Это выглядит ... очень похоже на предыдущую версию, как вы можете видеть: Последняя (надеюсь: o)) версия счета за 2015 год

Вот новый миди-файл .

Первая версия BASH (темп отсутствует)

Почему я не подумал об этом первым ...: o)

Это на 22 байта меньше, чем с AWK, для того же результата

a=C3z;echo "X:1
K:A
CzCz$a$a$a3$a$a$a$a${a}3Cz$a$a$a${a}3CzCzCzCzC"

Как и предыдущая версия в AWK, в stdout записывается действительный файл обозначений «ABC» (спасибо Tobia за то, что выяснилось, что выражение «L» было необязательным)

Это выглядит так: последняя версия раздела "2015"

И это звучит так же, как в предыдущей версии .

Предыдущая версия в AWK (86 байт)

Вот новая версия; немного дольше, но с более точным временем. Я приведу первую версию ниже для сравнения / ссылки:

BEGIN{a="C3z";print"X:1\nK:A\nL:1/8\nCzCz"a a a"3"a a a a a"3Cz"a a a a"3CzCzCzCzCz";}

Это все еще действительный файл "abc", который выглядит так: счет 2015 года

Вот новый миди-файл (я ускорил темп, чтобы не превышать 30 секунд).

Первая версия в AWK (66 байт):

Это намного менее интересно, чем мой предыдущий ответ , но это намного короче, поэтому:

BEGIN{print"X:1\nK:A\nL:1/4\nCCC2C2C2zC2C2C2C2C2zCC2C2C2C2zCCCCC"}

В результате вы получите действительный файл «abc», который можно прочитать (в том числе) в EasyABC. Это будет выглядеть так: Оценка "2015" в азбуке Морзе

и это будет звучать так (файл midi) . +


Вы должны опубликовать его как ABC без упаковки AWK и получить награду!
Tobia

Тобиа, ABC - это формат файла, а не язык программирования. И до сих пор с 86 байтами это самый короткий ответ ... Вопрос теперь "достаточно ли результирующий звук достаточно близок к требованиям для того, чтобы ответ был действительным?"
LeFauve

Я бы тоже назвал это форматом файла, но на вики-странице, на которую ссылается OP, он указан как язык программирования Sound. Я поместил свой собственный ABC-файл в качестве записи вместе с более подходящей программой Csound. Давайте посмотрим, что они думают об этом.
Tobia

Вот в чем проблема с вики ... иногда люди, редактирующие их, делают ошибки: о). Много разных вещей можно назвать «языками программирования», но я думаю, что ABC не является одним из них. В любом случае, спасибо за то, что узнал "L", было необязательно. Это спасло мне пару байтов; o)
LeFauve

«Длинные сегменты должны быть как минимум в 3 раза длиннее коротких». Последняя показанная музыкальная линия не соответствует требованиям.
mbomb007

13

Машинный код x86 (файл .COM): 121 120 113 109 байт

HexDump:

00000000  b4 3e bb 01 00 cd 21 b4  3c 31 c9 ba 3e 01 cd 21  |.>....!.<1..>..!|
00000010  4a b4 09 cd 21 be 56 01  8a 0c 46 e8 0c 00 b1 32  |J...!.V...F....2|
00000020  e8 07 00 81 fe 6d 01 75  ef c3 88 cb c0 e3 07 c1  |.....m.u........|
00000030  e1 04 30 d2 b4 02 00 da  cd 21 e2 fa c3 2e 73 6e  |..0......!....sn|
00000040  64 00 00 00 18 ff ff ff  ff 00 00 00 02 00 00 10  |d...............|
00000050  00 00 00 00 01 24 33 33  99 99 99 66 99 99 99 99  |.....$33...f....|
00000060  99 66 33 99 99 99 99 66  33 33 33 33 33           |.f3....f33333|
0000006d

Может быть легко запущен под DosBox; выходной файл .SND с именем SND. Вот FLAC-версия его вывода (и здесь .COM-файл).

Комментируемая сборка:

    org 100h

start:
    ; close stdout
    mov ah,3eh
    mov bx,1
    int 21h
    ; open snd
    mov ah,3ch
    xor cx,cx
    mov dx,filename
    int 21h
    ; write the header
    ; we used the `snd` part of the header as file name, back off one byte
    dec dx
    mov ah,9h
    int 21h
    mov si,data
.l:
    ; data read cycle
    ; read the current byte in cl (zero-extending to 16-bit)
    ; notice that ch is already zero (at the first iteration it's 0 from the
    ; int 21h/3ch, then we are coming from gen, which leaves cx to zero)
    mov cl,[si]
    ; move to next byte
    inc si
    ; generate the tone
    call gen
    ; generate the pause
    mov cl,50
    call gen
    ; repeat until we reach the end of data
    cmp si,eof
    jne .l
    ; quit
    ret

gen:
    ; generate a sawtooth wave at sampling frequency/2 Hz
    ; receives length (in samples>>4) in cx, with lowest bit indicating if
    ; it has to write a wave or a pause
    mov bl,cl
    ; shift the rightmost bit all the way to the left; this kills the
    ; unrelated data and puts a 128 in bl (if cx & 1 != 0)
    shl bl,7
    ; rescale the samples number
    shl cx,4
    ; zero the starting signal
    xor dl,dl
    ; prepare the stuff for int 21h
    mov ah,2h
.l:
    ; increment the signal
    add dl,bl
    ; write it
    int 21h
    ; decrement iteration count and loop
    loop .l
    ret

    ; .SND file header (4096 samples, mono, PCM)
header:
    db "."
    ; we also use "snd" as the file name
filename:
    db "snd",0,0,0,24,0xff,0xff,0xff,0xff,0,0,0,2,0,0,0x10,0,0,0,0,1
    ; terminator for int 21h/ah=9h
    db '$'
data:
    ; generated by gendata.py
    incbin "data.dat"
eof:

Выше data.datприведено простое в использовании представление строки Морзе (младший бит: звук включен / выключен, верхние 7 бит: длина звука в сэмплах >> 4), сгенерированные скриптом Python:

#!/usr/bin/env python2
import sys

# source string
s = "..--- ----- .---- ....."
# samples
sr = 4096
conv =  {
            '.': 1 | (((sr/5) >> 4) & ~1),    # dot:   1/5 second, dI/dt=1
            '-': 1 | (((sr/5*3) >> 4) & ~1),  # line:  3/5 second, dI/dt=1
            ' ':     ((sr/5*2) >> 4) & ~1     # space: 2/5 second (+1/5 from the always-present pause), dI/dt=0 (silent)
        }
sys.stdout.write(''.join(chr(conv[a]) for a in s))

Вам не обязательно нужно расширение файла, если это может сэкономить вам четыре байта.
Мартин Эндер

4
@ MartinBüttner: на самом деле, это позволяет мне сохранить 3 байта. aИз a.sndпомещаются непосредственно перед заголовком СНДА, который начинается с .sndпоследующим нулевым байтом, так что я получаю .sndчасть бесплатно и я перерабатываю его нулевой терминатор. Кроме того, тот факт, что заголовок начинается на один байт после имени файла, позволяет мне использовать a inc dxдля перехода к заголовку (1 байт) вместо mov dx, header(3 байта). OTOH, если бы мне было позволено вызывать его в .sndодиночку, я мог бы сохранить два байта, но я не уверен, что реальный DOS позволил бы это (обработка расширения под DOS была довольно своеобразной).
Маттео Италия

Я провел несколько тестов с вызовом файла .SND: я попал .SNDна DosBox, SND~1на FreeDOS, и я ожидаю чего-то другого на «настоящей» DOS; таким образом, это определенно область «неопределенного поведения». В итоге я согласился с вызовом файла SND(на 1 байт меньше из-за удаленного a, сохраняя стоимость inc dx- которая становится dec dx).
Маттео Италия

8

Mathematica - 130

r = Riffle;
s = SoundNote;
Export["m.mid", 
 Sound@
   r[Flatten@
     r[
       s[0,.4(Boole@#+.5)]&/@Array[#>4&,5,5-#]&/@{2,0,1,5},
       (b=None~s~#&)@.6
     ],b@.2
   ]
]

Играть онлайн


О, вы также можете использовать инфиксную нотацию для Export, как "m.mid"~Export~Sound@....
Мартин Эндер

(b=None~s~#&)@.6должен быть (b=None~s~#&)@.4 Кроме того , вы можете сохранить 3 символов с помощьюr = Riffle; s = SoundNote; Export["m.mid", Sound@r[r[Table[s[0, If[{1, 2, 11}~MemberQ~k || k > 15, .2, .6]], {k, 20}], None~s~.2], None~s~.4, 11]]
DavidC

Мартин, но в каждом перерыве уже было .2 .4 + .2
DavidC

@DavidCarraher Ах, ты прав.
Мартин Эндер

7

Perl 5: 94 122 140

Файлы SND имеют более простые заголовки, не нужно печатать в двоичном формате. Эти версии производят моно SND-файл 8 кГц с именем «a»:

open A,'>a';print
A".snd",pack"N*",24,-1,2,8e3,1,map{(--$|x3)x(894261072>>$_&1?1600:400)}0..39

Файл результатов .

Старое решение. Создает 8-битный монофонический WAV-файл 1 кГц с именем «a»:

open
A,'>a';print
A pack"A4lA8lssllssA4ls*",RIFF,17040,WAVEfmt,16,1,1,(1e3)x2,1,8,data,17004,map{($_)x(894261072>>$v++&1?400:100)}(255,0)x20

Файл результатов .

Чтобы получить 122 символа, мне пришлось вставить заголовок в двоичном виде вместо упаковки, что затрудняет копирование кода. Экранированная версия:

open
A,'>a';print
A"RIFF\x90B\0\0WAVEfmt \0\0\0\0\0\xe8\0\0\xe8\0\0\0\0datalB\0\0",pack"s*",map{($_)x(894261072>>$v++&1?400:100)}(255,0)x20

Кодирование Base64 фактического решения 122 байтов:

b3BlbgpBLCc+YSc7cHJpbnQKQSJSSUZGkEIAAFdBVkVmbXQgEAAAAAEAAQDoAwAA6AMAAAEACABk
YXRhbEIAACIscGFjayJzKiIsbWFweygkXyl4KDg5NDI2MTA3Mj4+JHYrKyYxPzQwMDoxMDApfSgy
NTUsMCl4MjA=

Вы могли бы использовать .auрасширение, возможно. Отлично сработано!
Ф. Хаури

7

AWK: 172 170 байт

... и без использования какой-либо волновой библиотеки! (*)

BEGIN{for(;++i<204;){d=d"\177\177\n";D=D"\n\n"}t=d d d D;d=d D;T=D D D;u=t t t;print".snd\0\0\0\30\0\0\221\306\0\0\0\2\0\0\20\0\0\0\0\1"d d u T u t t T d u t T d d d d d}

Это выводит аудиофайл Sun au на стандартный вывод, который может быть воспроизведен vlc (среди прочего). Хотя формат файла au не имеет каких-либо ограничений частоты дискретизации, VLC отказывается воспроизводить любой файл с частотой дискретизации ниже 4096 Гц, поэтому я использовал эту частоту

РЕДАКТИРОВАТЬ: ссылка на полученный аудио файл на DropBox


(*) Не должно ли быть бонуса за это? ; О)


Вам не нужно место в d=d "\177... конкатенации. Это сохраняет байт. Но когда я проигрываю полученный аудиофайл, звучит так, как будто ему не хватает последнего разряда 5.
Марк Рид

Спасибо. Я сохранил второй байт с другой конкатенацией, используя тот же трюк. Я только что проверил аудио файл с vlc 2.1.1, и он звучит завершенным. Каким игроком вы пользовались?
LeFauve

Я использовал QuickTime Player на OS X. Я открыл его в VLC, и он звучит нормально, так что не берите в голову. Виновата Apple, а не твоя.
Марк Рид

7

Питон, 155

Использует встроенный волновой модуль Python.

import wave
n=wave.open(*"nw")
k=17837
n.setparams((2,2,k,0,"NONE",0))
h=k*1314709609
while h:[n.writeframes(`i%9`)for i in[0]*(2-h%2)*k+range(h%4*k)];h/=4

Пишет в файл с именем n.

Спасибо Sp3000 за предложение использовать списки для цикла (это помогло удалить немного отступов).

Послушай это:

https://soundcloud.com/bitpwner/morse-the-new-year-2015

Вот ссылка на SoundCloud, если у вас не работает встроенный проигрыватель.

Код комментария:

import wave
n=wave.open("n.wav","w")         # Open a wav file for writing
k=44100                            
n.setparams((2,2,k,0,"NONE","")) # Sets the minimal params for the wav file
w=n.writeframes
h=23450475295733                 # Contains base-4 morse: '.'=1, '-'=3, ' '=0
while h:
    for i in range(h%2*k):w(h%4*chr(i%99)) # Writes saw-tooth signal using i%99
    w((2-h%2)*k*" ")                       # Writes the pauses
    h/=4

Поскольку wэто побочный эффект, я думаю, что вы можете перечислить comp, чтобы сохранить два байта:while h:[w(h%4*chr(i%99))for i in range(h%2*k)];w((2-h%2)*k*" ");h/=4
Sp3000

@ Sp3000 оо ... не думал об этом = D. Спасибо!
Векторизация

Это может быть глупым вопросом, но если h делится на 4 для каждой итерации, как останавливается цикл while?
Дерек 朕 會 功夫

@Derek 朕 會 功夫 Для python, когда h становится 0, он оценивается как False, завершая цикл. Цикл while - это игра в гольф для извлечения значений в последовательности «11333033333013333011111» одно за другим.
Векторизация

@bitpwner Я понял, что 0 оценивается как ложное, но разве для всех положительных чисел, если вы поделите его на другое положительное число, вы не сможете получить 0 из него?
Дерек 朕 會 功夫

6

C #, 556 552 536 535 516 506 503 491 483 байта

Использует библиотеку Wav.Net .

using System;using System.Linq;namespace WavDotNet.Core{using S=Samples<float>;class P{static void Main(){var w=new WavFileWrite<float>("a",9999);var b=new Tools.Generators.Sawtooth(9999);Func<long,float,S>g=(t,a)=>b.Generate32Bit(new TimeSpan(t),99,a);var l=2500000;S x=g(l,1),y=g(l*3,1),z=g(l*3,0),_=g(l,0),v=new S(new[]{x,_,x,_,y,_,y,_,y,z,y,_,y,_,y,_,y,_,y,z,x,_,y,_,y,_,y,_,y,z,x,_,x,_,x,_,x,_,x}.SelectMany(c=>c).ToList());w.AudioData.Add(new Channel<float>(v,0));w.Flush();}}}

Вывод в файл с именем a.

Результат размещен на Dropbox

Ungolfed код:

using System;
using System.Linq;
namespace WavDotNet.Core
{
    using FloatSamples = Samples<float>;
    class P
    {
        static void Main()
        {
            var file = new WavFileWrite<float>("output.wav", 9999);
            var sawtoothGen = new Tools.Generators.Sawtooth(9999);
            Func<long, float, FloatSamples> generate = (t, amplitude) => sawtoothGen.Generate32Bit(new TimeSpan(t), 99, amplitude);
            var length = 2500000;
            FloatSamples shortBeep = generate(length, 1),
            longBeep = generate(length * 3, 1),
            shortPause = generate(length * 3, 0),
            longPause = generate(length, 0),
            allSamples = new FloatSamples(new[] { shortBeep, longPause, shortBeep, longPause, longBeep, longPause, longBeep, longPause, longBeep, shortPause,
                longBeep, longPause, longBeep, longPause, longBeep, longPause, longBeep, longPause, longBeep, shortPause, 
                shortBeep, longPause, longBeep, longPause, longBeep, longPause, longBeep, longPause, longBeep, shortPause, 
                shortBeep, longPause, shortBeep, longPause, shortBeep, longPause, shortBeep, longPause, shortBeep }
                .SelectMany(c => c).ToList());
            file.AudioData.Add(new Channel<float>(allSamples, 0)); // 0 == ChannelPositions.Mono
            file.Flush();
        }
    }
}

5

питон 3 2, 191 188 174 171 (нет библиотек)

WAV файлы невероятно просты. Хотел попробовать без библиотек. По каким-то причинам мои файлы, похоже, приводят к сбою проигрывателя Windows Media. Quicktimeработаетошибки в середине файла. Преобразование в большую частоту дискретизации с помощью Audition исправляет это.

Обновление : Реализованы некоторые оптимизации из ответа Perl. Теперь выходы только с именем nи в выборке 1000 Гц. Отредактировал информацию выше соответственно.

w,s=200*" ",50*"~~  "
a,b,c=s+w,3*s+w,2*w
open(*"nw").write("RIFF\xD46\0\0WAVEfmt \20\0\0\0\1\0\1\0\xE8\3\0\0\xE8\3\0\0\1\0\10\0data\xB06\0\0"+a*2+b*3+c+b*5+c+a+b*4+c+a*5)

Старая версия

w,s=1600*" ",200*"~~~~    "
a,b,c=s+w,3*s+w,2*w
open("n.wav","wb").write("RIFF\244\265\1\0WAVEfmt \20\0\0\0\1\0\1\0@\x1f\0\0@\x1f\0\0\1\0\10\0data\200\265\1\0"+a*2+b*3+c+b*5+c+a+b*4+c+a*5)

4

C # ~ 485 байт

Использование библиотеки Wav.Net .

using WavDotNet.Core;namespace System.Collections.Generic{using f=Single;class T{static void Main(){var i=new WavFileWrite<f>("x",8000);Func<long,Samples<f>>g=d=>new WavDotNet.Tools.Generators.Sawtooth(8000).Generate32Bit(new TimeSpan(d),600,1);var s=new List<f>();var k="..--- ----- .---- .....";foreach(var c in k){s.AddRange(c=='.'?g(2000000):g(6000000));s.AddRange(new f[1600]);if(c==' '){s.AddRange(new f[3200]);}}i.AudioData.Add(new Channel<f>(new Samples<f>(s),0));i.Flush();}}}

И вот вывод.

Читаемая версия,

using WavDotNet.Core;

namespace System.Collections.Generic
{
    using f = Single;

    class T
    {
        static void Main()
        {
            var i = new WavFileWrite<f>("x", 8000);
            Func<long, Samples<f>> g = d => new WavDotNet.Tools.Generators.Sawtooth(8000).Generate32Bit(new TimeSpan(d), 600, 1);
            var s = new List<f>();
            var k = "..--- ----- .---- .....";

            foreach (var c in k)
            {
                s.AddRange(c == '.' ? g(2000000) : g(6000000));
                s.AddRange(new f[1600]);

                if (c == ' ')
                {
                    s.AddRange(new f[3200]);
                }
            }

            i.AudioData.Add(new Channel<f>(new Samples<f>(s), 0));
            i.Flush();
        }
    }
}

Вы можете сохранить несколько байтов, поместив свой класс в пространство имен System.Collections.Generic (это действительно работает). Есть также некоторые ненужные пробелы, которые вы можете удалить.
ProgramFOX

4

C # 382 333 байта

Не использует никаких нестандартных библиотек, записывает wav со скоростью 8 битов на семпл 44100 сэмплов в секунду, что, как я надеюсь, является допустимым заголовком (похоже, он хорошо воспроизводится / загружается в WMP / .NET / Audacity).

Заголовок кодируется в формате base64, а азбука Морзе кодируется как сигнал включения / выключения, который сохраняется в одном длинном (64 бита), поскольку последние 5 битов такие же, как и первый.

Результат можно найти здесь

Гольф-код:

using System.IO;class P{static void Main(){using(var w=new FileStream("w.wav",FileMode.Create)){int i=0,d=9980;w.Write(System.Convert.FromBase64String("UklGRhCCCgBXQVZFZm10IBAAAAABAAEARKwAAESsAAABAAgAZGF0YeyBCgA="),0,44);for(var k=5899114207271221109L;i++<d*69;w.WriteByte((byte)(System.Math.Sin((k>>(i/d)%64&1)*i*0.1)*127+127)));}}}

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

using System.IO;

class P
{
    static void Main()
    {
        using(var w=new FileStream("w.wav",FileMode.Create))
        {
            int i=0,d=9980; // d is samples per tone

            // write wav header
            w.Write(System.Convert.FromBase64String("UklGRhCCCgBXQVZFZm10IBAAAAABAAEARKwAAESsAAABAAgAZGF0YeyBCgA="),0,44);

            for(var k=5899114207271221109L; // 0101000111011101110111010001110111011101110111000111011101110101 as long
                i++<d*69; // 69 is number of bits
                w.WriteByte((byte)(
                    System.Math.Sin(
                        (k>>(i/d)%64&1) // read bit (0 or 1)
                        *i*0.1) // mul by ticker (sin(0) = 0)
                    *127+127)) // make sensible
            );
        }
    }
}

Задача не требует, чтобы имя файла заканчивалось .wav, поэтому вы можете сохранить там 4 байта.
ProgramFOX

Хороший способ вписать 69-битный ШИМ-код в 64-битную константу. Я пытался что-то подобное, но, вероятно, я не мог сократить свой код, используя ваш метод.
nutki

2

Суперколлайдер , 625 605 байт

Представление аудио языка программирования!

Вывод записывается в файл bв формате AIFF. Проигрыватель Windows Media не может открыть его, но он прекрасно работает в VLC Media Player. Сгенерированный файл aявляется файлом OSC .

c=0;d=0;f={c=c+d;d=0.2;[c,[\s_new,\w,1001,0,0,\freq,800]]};g={c=c+d;d=0.2;[c,[\n_free,1001]]};h={c=c+d;d=0.6;[c,[\s_new,\w,1001,0,0,\freq,800]]};i={c=c+d;d=0.6;[c,[\n_free,1001]]};x=[f.value,g.value,f.value,g.value,h.value,g.value,h.value,g.value,h.value,i.value,h.value,g.value,h.value,g.value,h.value,g.value,h.value,g.value,h.value,i.value,f.value,g.value,h.value,g.value,h.value,g.value,h.value,g.value,h.value,i.value,f.value,g.value,f.value,g.value,f.value,g.value,f.value,g.value,f.value,i.value];Score.recordNRT(x,"morse.osc","Morse2015.aiff");SynthDef("w",{arg freq=440;Out.ar(0,SinOsc.ar(freq,0,0.2))}).writeDefFile;

Я создал несколько функций SuperCollider: fгенерирует короткий гудок, gкороткий перерыв, hдлинный гудок и iдлинный перерыв. SuperCollider нужны начальные позиции для каждой синусоидальной волны, а не длина, поэтому мне пришлось создавать функции, которые генерируют волну с правильной стартовой позицией, и я должен вызывать функции каждый раз, когда мне нужна синусоида. (Я не смог сохранить волну определенной длины в переменной для повторного использования). \wОпределение создается в конце блока кода.

На моем компьютере с Windows он не сохранял аудиофайл в том же каталоге, что и мой код, но в этом каталоге:

C:\Users\MyName\AppData\Local\VirtualStore\Program Files (x86)\SuperCollider-3.6.6

Результат размещен на Dropbox

Код с отступом:

c = 0;
d = 0;
f = { c=c+d;d=0.2;[ c, [ \s_new, \w, 1001, 0, 0,  \freq, 800 ] ] };
g = { c=c+d;d=0.2; [ c, [\n_free, 1001]] };
h = { c=c+d;d=0.6; [ c, [ \s_new, \w, 1001, 0, 0, \freq, 800]]};
i = { c=c+d;d=0.6;[ c, [\n_free, 1001]] };

x = [ f.value, g.value, f.value, g.value, h.value, g.value, h.value, g.value, h.value, i.value,
      h.value, g.value, h.value, g.value, h.value, g.value, h.value, g.value, h.value, i.value,
      f.value, g.value, h.value, g.value, h.value, g.value, h.value, g.value, h.value, i.value,
    f.value, g.value, f.value, g.value, f.value, g.value, f.value, g.value, f.value, i.value
];

Score.recordNRT(x, "morse.osc", "Morse2015.aiff");

SynthDef("w",{ arg freq = 440;
    Out.ar(0,
         SinOsc.ar(freq, 0, 0.2)
    )
}).writeDefFile;

2

Чук - 1195 217 201 147 145 144

ChucK - это язык аудио программирования. bitpwner помог мне уменьшить это с 201 байта до 147 байтов.

SinOsc s;WvOut w=>blackhole;"y"=>w.wavFilename;int j;for(1016835=>int i;i>0;2/=>i){s=>w;j++;(i%2?200:600)::ms=>now;s=<w;(j%5?200:600)::ms=>now;}

Вот прямая ссылка на SoundCloud, если встроенный плеер не работает для вас.


1
Мне удалось сократить его до 164 с помощью аналогичной уловки, использованной в моем ответе:WvOut w=>blackhole;"x"=>w.wavFilename;SinOsc s=>w;0=>int j;for(1016835=>int i;i>0;2/=>i){j++;300=>s.freq;(600-i%2*400)::ms=>now;s=<w;(j%5>0?200:600)::ms=>now;s=>w;}
Векторизация

@bitpwner Вы используете, jчтобы избежать массива?
KSFT

Магическое число 1016835в двоичном виде есть 11111000010000000011. jнужно просто отслеживать паузы между каждой цифрой 2015(каждая цифра имеет 5 звуков).
Векторизовано

@bitpwner Ах, я даже этого не заметил. Это действительно крутая идея!
KSFT

Вы можете отредактировать это в своем ответе, чтобы иметь более высокую вероятность щедрости. ИМХО, улучшение не так уж много, чтобы оправдать новый ответ, так как вы уже проделали большую часть работы по выяснению Чака;)
Векторизация

2

Csound, 140 + 40 = 180

Аудио язык программирования.

Это файл оркестра:

instr 1
a1 oscil 2^15,990,1
out a1
endin

и это файл Score:

f1 0 512 10 1
t0 300
i1 0 1
i1 2
i1 40
i1 60
i1 62
i1 64
i1 66
i1 68
i1 4 3
i1 8
i1 12
i1 18
i1 22
i1 26
i1 30
i1 34
i1 42
i1 46
i1 50
i1 54

Размеры рассчитываются без учета дополнительных пробелов, однострочного терминатора (UNIX) и без терминатора после последней строки.

Вы вызываете их с помощью команды csound:

csound morse.org morse.sco

который создаст выходной файл в текущем каталоге, по умолчанию с именем «test.aif»

https://soundcloud.com/whatfireflies/morse-code-golf-in-csound/s-qzsaq

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

PS: Я новичок в Csound, любые советы по игре в гольф приветствуются, особенно в отношении файла результатов!


Ах, я с нетерпением ждал CSound. Если бы никто не опубликовал в нем ответ, я, вероятно, попытался бы написать его сам. :)
Мартин Эндер

1

брейкфук , 649 байт

++[>-[+>++[++<]>]>[>..........-..........+<-]-[+>++[++<]>]>[....................-]<<<<<-]+++[>+++[>-[+>++[++<]>]>[>..........-..........+<-]<<<-]-[+>++[++<]>]>[....................-]<<<-]-[+>++[++<]>]>[....................-]+++++[>-[+>++[++<]>]>[....................-]+++[>-[+>++[++<]>]>[>..........-..........+<-]<<<-]<<<-]+++[>-[+>++[++<]>]>[....................-]<<<-]-[+>++[++<]>]>[>..........-..........+<-]++++[>-[+>++[++<]>]>[....................-]+++[>-[+>++[++<]>]>[>..........-..........+<-]<<<-]<<<-]++[>-[+>++[++<]>]>[....................-]<<<-]+++++[>-[+>++[++<]>]>[....................-]-[+>++[++<]>]>[>..........-..........+<-]<<<<<-]

Это генерирует последовательность 8-битных сэмплов без знака, которые могут воспроизводиться со скоростью 8000 сэмплов в секунду с помощью такого инструмента, как aplayв Linux. Кредит в таблицу констант БФ .

Попробуйте онлайн!

Несколько меньше в гольф

DIT DIT DAH DAH DAH
++[>
 -[+>++[++<]>]>[>..........-..........+<-]
 -[+>++[++<]>]>[....................-]
<<<<<-]
+++[>
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
 -[+>++[++<]>]>[....................-]
<<<-]
-[+>++[++<]>]>[....................-]
DAH DAH DAH DAH DAH
+++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
+++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DAH DAH DAH DAH
-[+>++[++<]>]>[>..........-..........+<-]
++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DIT DIT DIT DIT
+++++[>
 -[+>++[++<]>]>[....................-]
 -[+>++[++<]>]>[>..........-..........+<-]
<<<<<-]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.