Морс Новий рік


33

Це тижневий виклик №1. Тема: Аудіообробка

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

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

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

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

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

Зауважте, що ви потрібно написати аудіофайл. Ви не можете просто відтворювати звук, наприклад, використовуючи системні звукові сигнали. Вам дозволяється використовувати будь-яку бібліотеку для обробки формату файлів та створення аудіо, але ви не повинні використовувати вбудовані функції кодування Морзе.

Це кодовий гольф, тому найкоротша відповідь (у байтах) виграє.

Подумайте про посилання на завантаження отриманого аудіофайлу (на SoundCloud або подібному), щоб люди могли перевірити результат, не запускаючи ваш код. Якщо ви завантажуєте в SoundCloud, переконайтеся, що ввімкніть завантаження на вкладці Дозволи доріжки.

Якщо ваш вихід використовує досить незвичайний формат файлу, додайте трохи інформації про те, як відтворити його та / або перетворити його у більш поширений формат і завантажити його.

Приклад треку

Це приклад, створений вручну, трек, який відповідає специфікації та використовує шум для сегментів Морзе (фоновий шум мікрофона, якщо бути точним). Ось посилання на SoundCloud якщо вбудований програвач не працює для вас.

Деталі баунті

Я присуджую нагороду за найкоротший виступ мовою програмування аудіо , тобто мовою, призначеною для синтезу звуку. Цей список не повний, тому сміливо використовуйте іншу мову програмування аудіо, якщо ви знаєте її. Якщо ви не впевнені, чи якусь мову ви хочете використовувати класифікує як мову програмування аудіо, будь ласка, повідомте мене в коментарях чи в чаті , і ми можемо обговорити це.

Зауважте, що ваше подання все ще має відповідати всім правилам - зокрема, він повинен написати файл, який може бути неможливим для всіх мов програмування аудіо. Наприклад, наскільки я можу сказати, gibber може лише відтворювати звук, а не зберігати його у файл.


1
Додатковий виклик: зробіть це звуком по-справжньому приємно.
Каз Вулф

6
@Mew Як добре може звучати Морзе?
Мартін Ендер

1
Це в Brainf ** k зробить це дивним на стільки бонусних рівнях.
Щогли

@Mast Напевно, але, на жаль, BF не може записати у файл. ;) (Я переконуюсь, що я буду більш м'яким до цього наступного разу.)
Мартін Ендер

Чи вважаються формати музичних нотацій, які містять лише партитуру та відсутні аудіо (.mid, .abc, наведені нижче), прийнятними як "аудіофайл"? Що щодо форматів "трекера", які містять як зразки, так і партитуру, але не надають аудіозапис (.mod, .xm)?
Тобія

Відповіді:


4

AWK BASH: 66 86 67 74 байт

За запитом Мартіна Бюттнера, я додав темп, оскільки після перевірки стандарту ABC Notation , схоже, для цього немає визначеного значення за замовчуванням (дякую нуті за вказівку на це).
Я також записую у файл диска (a) замість 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 секунд.

Це виглядає ... дуже схоже на попередню версію, як ви бачите: Last (I hope :o) ) version of 2015's score

Ось новий файл midi .

Перша версія 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" (дякую Тобіа, що з'ясував, що заява "L" не є обов'язковою)

Це виглядає приблизно так: last version of "2015" partition

І це звучить точно так, як попередня версія .

Попередня версія в 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", який виглядає приблизно так: score of 2015

Ось новий файл midi (я прискорив темп перебування під обмеженням 30 секунд).

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

Це набагато менш цікаво, ніж моя попередня відповідь , але набагато коротше, так що:

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

Це виводить дійсний файл "abc", який можна прочитати (серед інших) EasyABC. Це буде виглядати приблизно так: Score of "2015" in morse

і це буде звучати так (файл midi) . +


Ви повинні розмістити його як ABC без обгортання AWK та вимагати виграшу!
Тобія

Tobia, ABC - це формат файлу, а не мова програмування. І поки що з 86 байтами це найкоротша відповідь ... Питання зараз "чи отриманий звук достатньо близький до вимог, щоб відповідь була дійсною?"
LeFauve

Я б назвав це також файловим форматом, але вікі-сторінка, на якій ОП пов'язана, перелічує його як мову програмування звуку. Я подав власний файл ABC як запис, поряд із більш правильною програмою Csound. Подивимося, що вони думають про це.
Тобія

Ось проблема у вікі ... колись люди, що їх редагують, роблять помилки: o). Багато різних речей можна назвати "мовами програмування", але я думаю, що 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

Математика - 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

Перл 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 на stdout, який може відтворювати vlc (серед інших). Хоча формату файлу au не має обмеження швидкості вибірки, VLC відмовляється відтворювати будь-який файл із частотою дискретизації, меншою 4096 Гц, тому я використовував цю частоту

EDIT: Посилання на отриманий аудіофайл на DropBox


(*) Чи не повинен бути бонус за це? ; o)


Вам не потрібно місця в d=d "\177... конкатенації. Це економить байт. Але коли я відтворюю отриманий аудіофайл, то здається, що в ньому відсутній останній номер 5-го.
Марк Рид

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

Я використовував програму QuickTime Player на OS X. Я відкрив його у VLC, і це звучить прекрасно, так що не забувайте. Вина Apple, не ваша.
Марк Рід

7

Пітона, 155

Використовує вбудований хвильовий модуль пітона.

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це побічний ефект, я думаю, що ви можете перерахувати комп, щоб зберегти два байти:while h:[w(h%4*chr(i%99))for i in range(h%2*k)];w((2-h%2)*k*" ");h/=4
Sp3000

@ Sp3000 oo ... не думав про це = 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

Невикористаний код:

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 Player. Швидкістьпрацюєпомилки на півдорозі у файл. Перехід до більшої вибіркової швидкості за допомогою 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байт

Не використовує жодних нестандартних бібліотек, виписує 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

SuperCollider , 625 605 байт

Подання мови аудіо програмування!

Вихід записується у файл bу форматі AIFF. Програвач Windows Media не може його відкрити, але він працює чудово у медіаплеєрі VLC. Створений файл 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щоб уникнути масиву?
КСФТ

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

@bitpwner Ах, я навіть цього не помічав. Це дійсно класна ідея!
KSFT

Ви можете відредагувати його у відповідь, щоб мати більший шанс на виграш. imo, поліпшення не так багато, щоб виправдати нову відповідь sinc, ви вже зробили основну частину роботи, з'ясовуючи Чак;)
Векторизований

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. Зарахування до таблиці констант BF .

Спробуйте в Інтернеті!

Дещо менше гольфу

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.