Morse o Ano Novo


33

Este é o Desafio Semanal # 1. Tema: Processamento de Áudio

Sua tarefa é escrever um programa que grave um arquivo de áudio em disco (em um formato de sua escolha), que contenha o código Morse para 2015, ou seja,

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

Você é livre para escolher qualquer tipo de som para os segmentos, como uma onda senoidal de frequência única, um acorde, ruído, algum instrumento (por exemplo, usando arquivos MIDI), desde que audível. No entanto, existem algumas restrições no tempo:

  • Segmentos curtos precisam ter pelo menos 0,2 segundos de duração.
  • Os segmentos longos precisam ter pelo menos três vezes o tamanho dos segmentos curtos.
  • Quebras entre segmentos dentro de um dígito devem ter o mesmo comprimento que segmentos curtos.
  • Quebras entre dígitos devem ter o mesmo comprimento que segmentos longos.
  • Cada segmento e intervalo pode se desviar em até 10% do comprimento médio desse tipo de segmento / intervalo.
  • O arquivo de áudio inteiro não pode exceder 30 segundos.

Os intervalos não precisam ficar completamente silenciosos, mas os segmentos Morse devem ser audivelmente mais altos que os intervalos.

Observe que você precisa escrever um arquivo de áudio. Você não pode apenas tocar o som, por exemplo, usando bipes do sistema. Você tem permissão para usar qualquer tipo de biblioteca para lidar com o formato de arquivo e a geração de áudio, mas não deve usar recursos internos para a codificação Morse.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.

Por favor, considere vincular a um upload do arquivo de áudio resultante (no SoundCloud ou similar), para que as pessoas possam conferir o resultado sem precisar executar seu código. Se você fizer o upload para o SoundCloud, ative os downloads na guia Permissões da faixa.

Se sua saída usar um formato de arquivo bastante incomum, adicione algumas informações sobre como reproduzi-la e / ou convertê-la para um formato mais comum e carregá-la.

Exemplo de faixa

Esta é uma faixa de exemplo gerada manualmente que está em conformidade com as especificações e usa ruído para os segmentos Morse (ruído de fundo do microfone, para ser mais preciso). Aqui está um link para o SoundCloud se o player incorporado não funcionar para você.

Detalhes da recompensa

Atribuirei a recompensa ao envio mais curto em uma linguagem de programação de áudio , ou seja, uma linguagem projetada para sintetizar som. Essa lista não está completa, portanto, fique à vontade para usar outra linguagem de programação de áudio, se você souber uma. Se você não tiver certeza se algum idioma que deseja usar é classificado como idioma de programação de áudio, entre em contato nos comentários ou no bate-papo , e podemos discutir isso.

Observe que seu envio ainda precisa cumprir todas as regras - em particular, ele precisa gravar um arquivo, o que pode não ser possível em todas as linguagens de programação de áudio. Por exemplo, até onde eu sei, o gibber pode apenas tocar o som e não salvá-lo em um arquivo.


1
Desafio adicional: faça com que pareça realmente agradável.
Kaz Wolfe

6
@ Mew Quão bom Morse pode parecer?
Martin Ender

1
Fazer isso no Brainf ** k tornaria isso incrível em muitos níveis de bônus.
Mast

@ Master Provavelmente, mas infelizmente o BF não pode gravar em um arquivo. ;) (Eu vou fazer-se a ser mais tolerante com que da próxima vez).
Martin Ender

Os formatos de notação musical que contêm apenas a partitura e nenhum áudio (.mid, .abc visto abaixo) são considerados aceitáveis ​​como um "arquivo de áudio"? E os formatos "rastreador", que contêm amostras e uma pontuação, mas nenhuma trilha de áudio renderizada (.mod, .xm)?
Tobia

Respostas:


4

AWK BASH: 66 86 67 74 bytes

Conforme solicitado por Martin Büttner, adicionei um tempo, pois após verificar o padrão da notação ABC , parece que não há um valor padrão definido para isso (obrigado nutki por apontar isso).
Também escrevo em um arquivo de disco (a) em vez de STDOUT, pois a pergunta queria explicitamente "um arquivo em disco".

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

Eu coloquei um tempo de 99 que faz com que o arquivo de áudio dure 22 segundos; É mais lento que a minha versão anterior, mas pelo menos agora deve ter o mesmo tamanho em todos os reprodutores ABC e caber em menos de 30 segundos.

Parece ... muito parecido com a versão anterior, como você pode ver: Última (espero: o)) versão da pontuação de 2015

Aqui está o novo arquivo midi .

Primeira versão do BASH (falta o andamento)

Por que não pensei nisso primeiro ...: o)

Isso significa 22 bytes a menos que o AWK, para o mesmo resultado

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

Como a versão anterior no AWK, ele escreve no stdout um arquivo de notação "ABC" válido (obrigado Tobia por descobrir que a instrução "L" era opcional)

Se parece com isso: última versão da partição "2015"

E soa exatamente como a versão anterior .

Versão anterior no AWK (86 bytes)

Aqui está uma nova versão; um pouco mais, mas com um timing mais preciso. Deixei a primeira versão abaixo para comparação / referência:

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";}

Este ainda é um arquivo "abc" válido, com a seguinte aparência: pontuação de 2015

Aqui está o novo arquivo midi (eu acelerei o andamento para ficar abaixo do limite de 30 segundos).

Primeira versão no AWK (66 bytes):

Isso é muito menos interessante do que minha resposta anterior , mas é muito menor, então:

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

Isso gera um arquivo "abc" válido, que pode ser lido (entre outros) no EasyABC. Isso parecerá assim: Pontuação de "2015" em morse

e soará assim (arquivo midi) . +


Você deve publicá-lo como ABC sem a embalagem do AWK e reivindicar a recompensa!
Tobia

Tobia, ABC é um formato de arquivo, não uma linguagem de programação. E até agora, com 86 bytes, essa é a resposta mais curta ... A pergunta agora é "o som resultante está suficientemente próximo dos requisitos para que a resposta seja válida?"
LeFauve 6/15/15

Eu chamaria isso de formato de arquivo também, mas a página wiki vinculada ao OP o lista como uma linguagem de programação de som. Submeti meu próprio arquivo ABC como uma entrada, juntamente com um programa Csound mais adequado. Vamos ver o que eles pensam disso.
Tobia

Esse é o problema dos wikis ... algumas vezes as pessoas que os editam cometem erros: o). Muitas coisas diferentes podem ser chamadas de "linguagens de programação", mas acho que o ABC não é uma delas. De qualquer forma, obrigado por descobrir o "L" era opcional. Ele me salvou um par de bytes; o)
LeFauve

"Segmentos longos precisam ter pelo menos três vezes mais que segmentos curtos". A última linha de música exibida não atende aos requisitos.
mbomb007

13

código de máquina x86 (arquivo .COM): 121 120 113 109 bytes

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

Pode ser facilmente executado no DosBox; a saída é um arquivo .SND chamado SND. Aqui está uma versão FLAC de sua saída (e aqui o arquivo .COM).

Montagem comentada:

    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:

A data.datdescrição acima é uma representação fácil de usar da sequência morse (bit inferior: som ativado / desativado, superior a 7 bits: duração do som nas amostras >> 4) gerada por um script 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))

Você não precisa necessariamente de uma extensão de arquivo, se isso puder economizar quatro bytes.
Martin Ender

4
@ MartinBüttner: na verdade, ele permite salvar 3 bytes. O ade a.sndé colocado logo antes do cabeçalho do SND, que começa com .sndum byte zero, então eu pego a .sndpeça gratuitamente e reciclo seu terminador zero. Além disso, o fato de o cabeçalho iniciar um byte após o nome do arquivo permite que eu use a inc dxpara mover para o cabeçalho (1 byte) em vez de mov dx, header(3 bytes). OTOH, se eu tivesse permissão para chamá-lo .sndsozinho, poderia salvar dois bytes, mas não tenho certeza se o DOS real permitiria isso (o tratamento da extensão no DOS era bastante peculiar).
Matteo Italia

Fiz alguns testes chamando o arquivo .SND: entrei .SNDno DosBox, SND~1no FreeDOS e espero algo mais no DOS "real"; portanto, é definitivamente a área "comportamento indefinido". No final, resolvi chamar o arquivo SND(1 byte a menos devido à remoção a, mantendo o custo do inc dx- que se torna dec dx).
Matteo Italia

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

Jogue online


Oh, você também pode usar notação infix para Export, como "m.mid"~Export~Sound@....
Martin Ender

(b=None~s~#&)@.6deve ser (b=None~s~#&)@.4 Além disso, você pode salvar 3 caracteres usandor = 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/15

Martin, mas já havia 0,2 em cada intervalo. .4 + .2
DavidC

@DavidCarraher Ah, você está certo.
Martin Ender

7

Perl 5: 94 122 140

Os arquivos SND têm cabeçalhos mais simples, sem necessidade de imprimir em binário. Esta versão produz um arquivo SND mono de 8khz chamado 'a':

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

O arquivo de resultado .

Solução antiga. Produz um arquivo WAV mono de 8khz de 8 bits chamado '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

O arquivo de resultado.

Para obter 122 caracteres, tive que colar o cabeçalho em binário, em vez de empacotá-lo, o que dificulta a cópia aqui. A versão de escape é:

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

Codificação Base64 da solução real de 122 bytes:

b3BlbgpBLCc+YSc7cHJpbnQKQSJSSUZGkEIAAFdBVkVmbXQgEAAAAAEAAQDoAwAA6AMAAAEACABk
YXRhbEIAACIscGFjayJzKiIsbWFweygkXyl4KDg5NDI2MTA3Mj4+JHYrKyYxPzQwMDoxMDApfSgy
NTUsMCl4MjA=

Você poderia usar .auextensão, talvez. Bem feito!
F. Hauri 08/01

7

AWK: 172 170 bytes

... e sem usar nenhuma biblioteca wave! (*)

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}

Isso gera um arquivo de áudio Sun au no stdout que pode ser reproduzido pelo vlc (entre outros). Enquanto o formato de arquivo au não possui nenhuma limitação de taxa de amostragem, o VLC se recusa a reproduzir qualquer arquivo com uma taxa de amostragem inferior a 4096 Hz, então usei essa frequência

EDIT: Link para o arquivo de áudio resultante no DropBox


(*) Não deveria haver um bônus por isso? ; o)


Você não precisa do espaço na d=d "\177... concatenação. Isso economiza um byte. Mas quando eu reproduzo o arquivo de áudio resultante, parece que está faltando o último toque do 5. #
Mark Reed

Obrigado. Salvei um segundo byte com outra concatenação usando o mesmo truque. Acabei de verificar o arquivo de áudio com o vlc 2.1.1 e parece completo. Qual jogador você usou?
LeFauve

Eu estava usando o QuickTime Player no OS X. Abri-o no VLC e parece bom, então não importa. Culpa da Apple, não sua.
Mark Reed

7

Python, 155

Usa o módulo wave incorporado do 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

Grava em um arquivo chamado n .

Agradecemos ao Sp3000 pela sugestão de usar a compreensão da lista para loop (isso ajudou a remover um pouco de recuo).

Escute isto:

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

Aqui está um link para o SoundCloud se o player incorporado não funcionar para você.

Código comentado:

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

Desde wé um efeito colateral Eu acho que você pode listar comp para salvar dois bytes: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 ... não pensei nisso = D. THX!
Vetorizado

Essa pode ser uma pergunta estúpida, mas se h é dividido por 4 para cada iteração, como o loop while para?
Derek

@Derek Para python, quando h se torna 0, ele avalia como False, encerrando o loop. O loop while é um truque de golfe para extrair os valores na sequência "11333033333013333011111" um por um.
Vetorizado

@bitpwner Eu entendo que 0 é avaliado como falso, mas não é isso para todos os números positivos, se você o dividir por outro número positivo, não há como obter um 0 com isso?
Derek

6

C #, 556 552 536 535 516 506 503 491 483 bytes

Usa a biblioteca 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();}}}

Saídas para um arquivo chamado a.

Resultado hospedado no Dropbox

Código não destruído:

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

Python 3 2 191 188 174 171 (sem bibliotecas)

Arquivos Wav são incrivelmente simples. Queria tentar sem bibliotecas. Por alguma razão, meus arquivos parecem travar o Windows Media Player. Tempo rápidotrabalhobugs no meio do arquivo. A conversão para uma taxa de amostragem maior usando o Audition corrige isso.

Atualização : implementadas algumas otimizações da resposta Perl. Agora é emitido apenas com o nome ne na amostragem de 1000Hz. Informações editadas acima em conformidade.

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)

Versão antiga

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

Bytes em C # ~ 485

Usando a biblioteca 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();}}}

E aqui está a saída.

Versão legível,

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

Você pode salvar alguns bytes, agrupando sua classe dentro do espaço de nome System.Collections.Generic (que realmente funciona). Há também alguns espaços em branco desnecessários que você pode remover.
ProgramFOX

4

C # 382 333 bytes

Não usa bibliotecas não padrão, escreve um wav de 44100 amostras por segundo de 8 bits por amostra, com o que eu espero que seja um cabeçalho válido (parece reproduzir / carregar felizmente no WMP / .NET / Audacity).

O cabeçalho é codificado em base64 e o morse é codificado como sinal on / off, que é armazenado em um único comprimento (64 bits) porque os últimos 5 bits são os mesmos que o primeiro.

O resultado pode ser encontrado aqui

Código de golfe:

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

Com comentários:

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

O desafio não exige que o nome do arquivo termine .wav, para que você possa salvar 4 bytes lá.
ProgramFOX

Ótima maneira de ajustar o código PWM de 69 bits em uma constante de 64 bits. Eu estava tentando algo assim, mas provavelmente não consegui reduzir meu código usando seu método.
nutki

2

SuperCollider , 625 605 bytes

Envio de linguagem de programação de áudio!

A saída é gravada em um arquivo bno formato AIFF. O Windows Media Player falha ao abri-lo, mas funciona bem no VLC media player. O arquivo gerado aé um arquivo 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;

Criei algumas funções do SuperCollider: fgera um bipe curto, gum intervalo curto, hum bipe longo e ium intervalo longo. O SuperCollider precisa das posições iniciais para cada onda senoidal e não de um comprimento, então eu tive que criar funções que geram uma onda com a posição inicial correta e preciso chamar as funções toda vez que precisar de uma onda senoidal. (Não foi possível armazenar uma onda com um comprimento específico em uma variável para reutilização). A \wdefinição é criada no final do bloco de código.

No meu computador com Windows, ele não salvou o arquivo de áudio no mesmo diretório que o meu código, mas neste diretório:

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

Resultado hospedado no Dropbox

Código com recuo:

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

ChucK - 1195 217 201 147 145 144

ChucK é uma linguagem de programação de áudio. O bitpwner me ajudou a reduzir isso de 201 para 147 bytes.

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

Aqui está um link direto para o SoundCloud se o player incorporado não funcionar para você.


1
Consegui reduzi-lo para 164 com um truque semelhante usado na minha resposta: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;}
Vectorized

@bitpwner Você está usando jpara evitar a matriz?
KSFT

O número mágico 1016835em binário é 11111000010000000011. jexiste apenas para acompanhar as pausas entre cada dígito de 2015(cada dígito tem 5 sons).
Vetorizado

@bitpwner Ah, eu nem percebi isso. Essa é uma ideia muito legal!
KSFT

Você pode editá-lo na sua resposta para ter uma chance maior de recompensa. imo, a melhoria não é muito para justificar uma nova resposta sinc você já fez a maior parte do trabalho descobrindo Chuck;)
Vectorized

2

Csound, 140 + 40 = 180

Linguagem de programação de áudio.

Este é o arquivo da orquestra:

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

e este é o arquivo de pontuação:

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

Os tamanhos são calculados assumindo espaço em branco extra, terminador de linha única (UNIX) e nenhum terminador após a última linha.

Você os chama usando o comando csound:

csound morse.org morse.sco

que produzirá um arquivo de saída no diretório atual, por padrão chamado "test.aif"

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

Eu poderia ter raspado dois ou três bytes escolhendo uma forma de onda mais feia, mas gosto do som da tradicional onda senoidal de Morse.

PS: Eu sou um novato em Csound, todas as dicas de golfe são apreciadas, especialmente no que diz respeito à pontuação!


Ah, eu estava ansioso pelo CSound. Se ninguém tivesse postado uma resposta, eu provavelmente teria tentado escrever uma. :)
Martin Ender

1

brainfuck , 649 bytes

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

Isso gera uma sequência de amostras não assinadas de 8 bits que podem ser reproduzidas em 8000 amostras por segundo com uma ferramenta como aplayno Linux. Crédito na tabela de constantes BF .

Experimente online!

Um pouco menos jogado

DIT DIT DAH DAH DAH
++[>
 -[+>++[++<]>]>[>..........-..........+<-]
 -[+>++[++<]>]>[....................-]
<<<<<-]
+++[>
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
 -[+>++[++<]>]>[....................-]
<<<-]
-[+>++[++<]>]>[....................-]
DAH DAH DAH DAH DAH
+++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
+++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DAH DAH DAH DAH
-[+>++[++<]>]>[>..........-..........+<-]
++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DIT DIT DIT DIT
+++++[>
 -[+>++[++<]>]>[....................-]
 -[+>++[++<]>]>[>..........-..........+<-]
<<<<<-]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.