Morse el año nuevo

33

Este es el desafío semanal n. ° 1. Tema: Procesamiento de audio

Su tarea es escribir un programa, que escribe un archivo de audio en el disco (en un formato de su elección), que contiene el código Morse para 2015, es decir

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

Usted es libre de elegir cualquier tipo de sonido para los segmentos, como una onda sinusoidal de frecuencia única, un acorde, ruido, algún instrumento (por ejemplo, usando archivos MIDI), siempre que sea audible. Sin embargo, hay algunas limitaciones en el tiempo:

  • Los segmentos cortos deben tener al menos 0.2 segundos de longitud.
  • Los segmentos largos deben ser al menos 3 veces más largos que los segmentos cortos.
  • Los saltos entre segmentos dentro de un dígito deben tener la misma longitud que los segmentos cortos.
  • Los saltos entre dígitos deben tener la misma longitud que los segmentos largos.
  • Cada segmento y ruptura puede desviarse hasta un 10% de la longitud promedio de ese tipo de segmento / ruptura.
  • El archivo de audio completo no puede durar más de 30 segundos.

Los descansos no necesitan ser completamente silenciosos, pero los segmentos Morse deberían ser audiblemente más fuertes que los descansos.

Tenga en cuenta que tiene que escribir un archivo de audio. No puede simplemente reproducir el sonido, por ejemplo, utilizando pitidos del sistema. Puede usar cualquier tipo de biblioteca para manejar el formato de archivo y la generación de audio, pero no debe usar las funciones integradas para la codificación Morse.

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Considere vincular a una carga del archivo de audio resultante (en SoundCloud o similar), para que las personas puedan ver el resultado sin tener que ejecutar su código. Si carga en SoundCloud, asegúrese de habilitar las descargas en la pestaña Permisos de la pista.

Si su salida utiliza un formato de archivo poco común, agregue información sobre cómo reproducirlo y / o conviértalo a un formato más común y cárguelo.

Pista de ejemplo

Esta es una pista de ejemplo generada manualmente que se ajusta a la especificación y utiliza ruido para los segmentos Morse (ruido de fondo del micrófono, para ser precisos). Aquí hay un enlace a SoundCloud si el reproductor incorporado no funciona para usted.

Detalles de la recompensa

Otorgaré la recompensa al envío más breve en un lenguaje de programación de audio , es decir, un lenguaje diseñado para sintetizar sonido. Esa lista no está completa, así que siéntase libre de usar otro lenguaje de programación de audio, si conoce uno. Si no está seguro de si algún lenguaje que desea utilizar se clasifica como un lenguaje de programación de audio, hágamelo saber en los comentarios o en el chat , y podemos discutirlo.

Tenga en cuenta que su envío aún debe cumplir con todas las reglas, en particular, tiene que escribir un archivo, que podría no ser posible en todos los lenguajes de programación de audio. Por ejemplo, por lo que puedo decir, gibber solo puede reproducir el sonido y no guardarlo en un archivo.

Martin Ender
fuente
1
Reto adicional: haz que suene realmente bien.
Kaz Wolfe
66
@Mew ¿Qué tan agradable puede sonar Morse?
Martin Ender
1
Hacer esto en Brainf ** k lo haría increíble en tantos niveles de bonificación.
Mástil
@Mast Probablemente, pero desafortunadamente, BF no puede escribir en un archivo. ;) (Me aseguraré de ser más indulgente con eso la próxima vez.)
Martin Ender
¿Se consideran aceptables como "archivos de audio" los formatos de notación musical, que solo contienen la partitura y no hay audio (.mid, .abc visto a continuación)? ¿Qué pasa con los formatos "tracker", que contienen muestras y una partitura, pero no una pista de audio renderizada (.mod, .xm)?
Tobia

Respuestas:

4

AWK BASH: 66 86 67 74 bytes

Según lo solicitado por Martin Büttner, agregué un tempo ya que después de verificar el estándar de notación ABC , parece que no hay un valor predeterminado definido para esto (gracias nutki por señalar esto).
También escribo en un archivo de disco (a) en lugar de STDOUT ya que la pregunta quería explícitamente "un archivo en el 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

Puse un tempo de 99 que hace que el archivo de audio dure 22 segundos; Es más lento que mi versión anterior, pero al menos ahora se supone que tiene la misma longitud en todos los jugadores de ABC, y se ajusta a menos de 30 segundos.

Se ve ... muy parecido a la versión anterior como puedes ver: Última (espero: o)) versión del puntaje de 2015

Aquí está el nuevo archivo midi .

Primera versión de BASH (falta el tempo)

¿Por qué no pensé en esto primero ...: o)

Eso es 22 bytes menos que con AWK, para el mismo resultado

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

Al igual que la versión anterior en AWK, escribe en stdout un archivo de notación "ABC" válido (gracias Tobia por descubrir que la declaración "L" era opcional)

Se parece a esto: última versión de la partición "2015"

Y suena exactamente como la versión anterior .

Versión anterior en AWK (86 Bytes)

Aquí hay una nueva versión; un poco más, pero con una sincronización más precisa. Dejo la primera versión a continuación para comparación / referencia:

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 sigue siendo un archivo "abc" válido, que se ve así: puntaje de 2015

Aquí está el nuevo archivo midi (aceleré el tempo para permanecer por debajo del límite de 30 segundos).

Primera versión en AWK (66 Bytes):

Esto es mucho menos interesante que mi respuesta anterior , pero es mucho más corto, así que:

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

Esto genera un archivo "abc" válido, que puede leerse (entre otros) en EasyABC. Se verá así: Puntuación de "2015" en morse

y sonará así (archivo midi) . +

LeFauve
fuente
¡Debes publicarlo como ABC sin el envoltorio AWK y reclamar la recompensa!
Tobia
Tobia, ABC es un formato de archivo, no un lenguaje de programación. Y hasta ahora con 86 bytes, esta es la respuesta más corta ... La pregunta ahora es "¿el sonido resultante está lo suficientemente cerca de los requisitos para que la respuesta sea válida?"
LeFauve
También lo habría llamado formato de archivo, pero la página wiki que el OP enlazó lo enumera como un lenguaje de programación de sonido. He enviado mi propio archivo ABC como entrada, junto con un programa Csound más adecuado. Veamos qué piensan de eso.
Tobia
Ese es el problema con los wikis ... a veces las personas que los editan cometen errores: o). Muchas cosas diferentes se pueden llamar "lenguajes de programación", pero creo que ABC no es uno de ellos. De todos modos, gracias por descubrir que la "L" era opcional. Me ahorró un par de bytes; o)
LeFauve
"Los segmentos largos deben ser al menos 3 veces más largos que los segmentos cortos". La última línea de música que se muestra no cumple los requisitos.
mbomb007
13

Código de máquina x86 (archivo .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

Se puede ejecutar fácilmente en DosBox; la salida es un archivo .SND llamado SND. Aquí hay una versión FLAC de su salida (y aquí el archivo .COM).

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

Lo que se data.datincluye arriba es una representación fácil de usar de la cadena Morse (bit inferior: sonido activado / desactivado, superior 7 bits: longitud del sonido en muestras >> 4) generada por un script de 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))
Matteo Italia
fuente
No necesariamente necesita una extensión de archivo, si eso puede ahorrarle cuatro bytes.
Martin Ender
44
@ MartinBüttner: en realidad, me permite guardar 3 bytes. El aof a.sndse coloca justo antes del encabezado SND, que comienza .sndseguido de un byte cero, por lo que obtengo la .sndpieza de forma gratuita y reciclo su terminador cero. Además, el hecho de que el encabezado comienza un byte después del nombre del archivo me permite usar a inc dxpara mover al encabezado (1 byte) en lugar de a mov dx, header(3 bytes). OTOH, si se me permitiera llamarlo .sndsolo, podría guardar dos bytes, pero no estoy seguro de que el DOS real lo permita (el tratamiento de la extensión bajo DOS fue bastante peculiar).
Matteo Italia
Hice algunas pruebas al llamar al archivo .SND: me puse .SNDen DosBox, SND~1en FreeDOS, y espero algo más en DOS "real"; por lo tanto, definitivamente es un área de "comportamiento indefinido". Al final, decidí llamar al archivo SND(1 byte menos debido a que se eliminó a, manteniendo el costo de lo inc dxque se convierte 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
     ],[email protected]
   ]
]

Jugar en linea

silbido
fuente
Oh, también puedes usar notación infija para Export, como "m.mid"~Export~Sound@....
Martin Ender
(b=None~s~#&)@.6(b=None~s~#&)@.4 También debería , puede guardar 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
Martin, Pero ya había un .2 en cada descanso. .4 + .2
DavidC
@DavidCarraher Ah, tienes razón.
Martin Ender
7

Perl 5: 94122 140

Los archivos SND tienen encabezados más simples, no es necesario imprimir en binario. Esta versión produce un archivo SND mono de 8khz llamado 'a':

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

El archivo de resultados .

Antigua solución Produce un archivo WAV mono de 8 bits de 1 kHz llamado '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

El archivo de resultados .

Para llegar a 122 caracteres, tuve que pegar el encabezado en binario en lugar de empaquetarlo, lo que hace que el código sea difícil de copiar aquí. La versión escapada es:

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

Codificación Base64 de la solución real de 122 bytes:

b3BlbgpBLCc+YSc7cHJpbnQKQSJSSUZGkEIAAFdBVkVmbXQgEAAAAAEAAQDoAwAA6AMAAAEACABk
YXRhbEIAACIscGFjayJzKiIsbWFweygkXyl4KDg5NDI2MTA3Mj4+JHYrKyYxPzQwMDoxMDApfSgy
NTUsMCl4MjA=
nutki
fuente
U podría usar la .auextensión, tal vez. ¡Bien hecho!
F. Hauri
7

AWK: 172 170 bytes

... y sin usar ninguna biblioteca de ondas! (*)

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}

Esto genera un archivo de audio Sun au en stdout que puede reproducirse mediante vlc (entre otros). Si bien el formato de archivo au no tiene ninguna limitación de frecuencia de muestreo, VLC se niega a reproducir cualquier archivo con una frecuencia de muestreo inferior a 4096 Hz, por lo que utilicé esta frecuencia

EDITAR: Enlace al archivo de audio resultante en DropBox


(*) ¿No debería haber una bonificación por esto? ; o)

LeFauve
fuente
No necesitas el espacio en la d=d "\177... concatenación. Eso ahorra un byte. Pero cuando reproduzco el archivo de audio resultante, parece que falta el último dit de los 5.
Mark Reed
Gracias. Ahorré un segundo byte con otra concatenación usando el mismo truco. Acabo de comprobar el archivo de audio con vlc 2.1.1 y suena completo. ¿Qué jugador usaste?
LeFauve
Estaba usando QuickTime Player en OS X. Lo abrí en VLC y suena bien, así que no importa. La culpa de Apple, no la tuya.
Mark Reed
7

Python, 155

Utiliza el módulo de onda incorporado de 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

Escribe en un archivo llamado n.

Gracias Sp3000 por su sugerencia sobre el uso de la comprensión de la lista para el bucle (esto ayudó a eliminar un poco de sangría).

Escúchalo:

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

Aquí hay un enlace a SoundCloud si el reproductor incorporado no funciona para usted.

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
Vectorizado
fuente
Dado que wes un efecto secundario, creo que puede enumerar comp para guardar dos 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 ... no pensé en eso = D. ¡Gracias!
Vectorizado
Esta podría ser una pregunta estúpida, pero si h se divide por 4 para cada iteración, ¿cómo se detiene el ciclo while?
Derek 朕 會 功夫
@Derek 朕 會 功夫 Para python, cuando h se convierte en 0, se evalúa como False, finalizando el ciclo. El ciclo while es un truco de golf para extraer los valores en la secuencia "11333033333013333011111" uno por uno.
Vectorizado
@bitpwner Entiendo que 0 se evalúa como falso, pero ¿no es así para todos los números positivos, si lo divide por otro número positivo, no hay forma de obtener un 0?
Derek 朕 會 功夫
6

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

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

Salidas a un archivo llamado a.

Resultado alojado en Dropbox

Código sin golf:

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

Pitón 3 2, 191 188 174 171 (sin bibliotecas)

Los archivos Wav son increíblemente simples. Quería probar sin bibliotecas. Por alguna razón, mis archivos parecen bloquear el Reproductor de Windows Media. Tiempo rapidotrabajoserrores a mitad de camino en el archivo. La conversión a una frecuencia de muestreo mayor usando Audition corrige esto.

Actualización : Implementé algunas optimizaciones de la respuesta de Perl. Ahora sale solo con el nombre ny en muestreo de 1000Hz. Información editada arriba en consecuencia.

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)

Versión antigua

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)
PurkkaKoodari
fuente
4

C # ~ 485 bytes

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

Y aquí está la salida.

Versión legible,

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();
        }
    }
}
Sam
fuente
Puede guardar algunos bytes envolviendo su clase dentro del espacio de nombres System.Collections.Generic (que realmente funciona). También hay algunos espacios en blanco innecesarios que puede eliminar.
ProgramFOX
4

C # 382 333bytes

No utiliza ninguna biblioteca no estándar, escribe un wav de 8 bits por muestra 44100 muestras por segundo, con lo que espero sea un encabezado válido (parece reproducir / cargar felizmente en WMP / .NET / Audacity).

El encabezado está codificado en base64, y el morse está codificado como señal de encendido / apagado que se almacena en un solo largo (64 bits) porque los últimos 5 bits son los mismos que el primero.

El resultado se puede encontrar aquí.

Código de golf:

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

Con comentarios:

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
            );
        }
    }
}
VisualMelon
fuente
El desafío no requiere que termine el nombre del archivo .wav, por lo que puede guardar 4 bytes allí.
ProgramFOX
Buena manera de ajustar el código PWM de 69 bits en una constante de 64 bits. Estaba intentando algo así, pero probablemente no podría acortar mi código usando su método.
nutki
2

SuperCollider , 625 605 bytes

Envío de lenguaje de programación de audio!

La salida se escribe en un archivo ben formato AIFF. Windows Media Player no puede abrirlo, pero funciona bien en el reproductor multimedia VLC. El archivo generado aes un archivo 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;

Creé algunas funciones de SuperCollider: fgenera un pitido corto, gun breve descanso, hun pitido largo y iun descanso largo. SuperCollider necesita las posiciones iniciales para cada onda sinusoidal y no una longitud, por lo que tuve que crear funciones que generen una onda con la posición inicial correcta y tengo que llamar a las funciones cada vez que necesito una onda sinusoidal. (No pude almacenar una onda con una longitud específica en una variable para reutilizar). La \wdefinición se crea al final del bloque de código.

En mi computadora con Windows, no guardó el archivo de audio en el mismo directorio que mi código, pero en este directorio:

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

Resultado alojado en Dropbox

Código con sangría:

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;
ProgramFOX
fuente
2

ChucK - 1195 217 201 147 145 144

ChucK es un lenguaje de programación de audio. bitpwner me ayudó a reducir esto de 201 bytes a 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;}

Aquí hay un enlace directo a SoundCloud si el reproductor incorporado no funciona para usted.

KSFT
fuente
1
Logré reducirlo a 164 con un truco similar usado en mi respuesta: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;}
Vectorizado el
@bitpwner ¿Estás utilizando jpara evitar la matriz?
KSFT
El número mágico 1016835en binario es 11111000010000000011. jestá ahí para simplemente hacer un seguimiento de las pausas entre cada dígito de 2015(cada dígito tiene 5 sonidos).
Vectorizado el
@bitpwner Ah, ni siquiera me di cuenta de eso. ¡Esa es una idea genial!
KSFT
Puede editarlo en su respuesta para tener una mayor probabilidad de recompensa. OMI, la mejora no es mucho para justificar una nueva respuesta porque ya hiciste la mayor parte del trabajo descubriendo a Chuck;)
Vectorizado el
2

Csound, 140 + 40 = 180

Lenguaje de programación de audio.

Este es el archivo de orquesta:

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

y este es el archivo de puntuación:

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

Los tamaños se calculan suponiendo que no haya espacios en blanco adicionales, un terminador de línea simple (UNIX) y ningún terminador después de la última línea.

Los invocas usando el comando csound:

csound morse.org morse.sco

que producirá un archivo de salida en el directorio actual, por defecto llamado "test.aif"

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

Podría haber afeitado dos o tres bytes eligiendo una forma de onda más fea, pero me gusta el sonido de la onda sinusoidal Morse tradicional.

PD: Soy un novato en Csound, se agradece cualquier consejo de golf, ¡especialmente en lo que respecta al archivo de puntaje!

Tobia
fuente
Ah, estaba esperando CSound. Si nadie hubiera publicado una respuesta, probablemente habría intentado escribirla yo mismo. :)
Martin Ender
1

brainfuck , 649 bytes

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

Esto genera una secuencia de muestras sin signo de 8 bits que se pueden reproducir a 8000 muestras por segundo con una herramienta como aplayen Linux. Crédito a la tabla de constantes BF .

Pruébalo en línea!

Algo menos golfizado

DIT DIT DAH DAH DAH
++[>
 -[+>++[++<]>]>[>..........-..........+<-]
 -[+>++[++<]>]>[....................-]
<<<<<-]
+++[>
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
 -[+>++[++<]>]>[....................-]
<<<-]
-[+>++[++<]>]>[....................-]
DAH DAH DAH DAH DAH
+++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
+++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DAH DAH DAH DAH
-[+>++[++<]>]>[>..........-..........+<-]
++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DIT DIT DIT DIT
+++++[>
 -[+>++[++<]>]>[....................-]
 -[+>++[++<]>]>[>..........-..........+<-]
<<<<<-]
techo
fuente