Morse il nuovo anno


33

Questa è la sfida settimanale n. 1. Tema: elaborazione audio

Il tuo compito è quello di scrivere un programma, che scrive un file audio su disco (in un formato a tua scelta), che contiene il codice Morse per 2015, ad es.

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

Sei libero di scegliere qualsiasi tipo di suono per i segmenti, come un'onda sinusoidale a singola frequenza, un accordo, rumore, alcuni strumenti (ad es. Usando file MIDI), purché sia ​​udibile. Tuttavia, ci sono alcuni vincoli sui tempi:

  • I segmenti corti devono avere una lunghezza di almeno 0,2 secondi.
  • I segmenti lunghi devono essere almeno 3 volte più lunghi dei segmenti corti.
  • Le interruzioni tra i segmenti all'interno di una cifra dovrebbero avere la stessa lunghezza dei segmenti corti.
  • Le interruzioni tra le cifre devono avere la stessa lunghezza dei segmenti lunghi.
  • Ogni segmento e interruzione possono discostarsi fino al 10% dalla lunghezza media di quel tipo di segmento / interruzione.
  • L'intero file audio non può superare i 30 secondi.

Le pause non devono essere completamente silenziose, ma i segmenti Morse dovrebbero essere udibilmente più rumorosi delle pause.

Si noti che è necessario scrivere un file audio. Non è possibile riprodurre l'audio, ad esempio utilizzando i segnali acustici di sistema. Puoi utilizzare qualsiasi tipo di libreria per gestire il formato del file e la generazione dell'audio, ma non devi utilizzare le funzionalità integrate per la codifica Morse.

Questo è il golf del codice, quindi vince la risposta più breve (in byte).

Prendi in considerazione il collegamento a un caricamento del file audio risultante (su SoundCloud o simile), in modo che le persone possano controllare il risultato senza dover eseguire il codice. Se carichi su SoundCloud, assicurati di abilitare i download nella scheda Autorizzazioni della traccia.

Se l'output utilizza un formato di file piuttosto insolito, aggiungere alcune informazioni su come riprodurlo e / o convertirlo in un formato più comune e caricarlo.

Traccia di esempio

Questa è una traccia di esempio generata manualmente che è conforme alle specifiche e utilizza il rumore per i segmenti Morse (rumore di fondo del microfono, per essere precisi). Ecco un link a SoundCloud se il lettore incorporato non funziona per te.

Dettagli sulla taglia

Assegnerò la generosità alla più breve presentazione in un linguaggio di programmazione audio , ovvero un linguaggio progettato per sintetizzare il suono. L'elenco non è completo, quindi sentiti libero di usare un altro linguaggio di programmazione audio, se ne conosci uno. Se non sei sicuro che una lingua che desideri utilizzare sia classificata come linguaggio di programmazione audio, faccelo sapere nei commenti o in chat e possiamo discuterne.

Tieni presente che il tuo invio deve ancora rispettare tutte le regole, in particolare deve scrivere un file, che potrebbe non essere possibile in tutti i linguaggi di programmazione audio. Ad esempio, per quanto ne so, Gibber può solo riprodurre il suono e non salvarlo in un file.


1
Sfida aggiuntiva: rendila davvero piacevole.
Kaz Wolfe,

6
@Mew Quanto può sembrare bello Morse?
Martin Ender,

1
Farlo in Brainf ** k lo renderebbe fantastico su così tanti livelli bonus.
Albero

@Mast Probabilmente, ma sfortunatamente, BF non può scrivere su un file. ;) (Mi assicurerò di essere più indulgente con quello la prossima volta.)
Martin Ender

I formati di notazione musicale, che contengono solo la partitura e nessun audio (.mid, .abc visti di seguito) sono considerati accettabili come "file audio"? Che dire dei formati "tracker", che contengono sia campioni che un punteggio, ma nessuna traccia audio renderizzata (.mod, .xm)?
Tobia,

Risposte:


4

BASK AWK : 66 86 67 74 byte

Come richiesto da Martin Büttner, ho aggiunto un tempo poiché dopo aver verificato lo standard della notazione ABC , sembra che non ci sia un valore predefinito definito per questo (grazie nutki per averlo indicato).
Scrivo anche in un file su disco (a) anziché in STDOUT poiché la domanda voleva esplicitamente "un file su 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

Ho messo un tempo di 99 che fa sì che il file audio duri 22 secondi; È più lento della mia versione precedente, ma almeno ora dovrebbe avere la stessa lunghezza su ogni lettore ABC e si adatta a meno di 30 secondi.

Sembra ... molto simile alla versione precedente come puoi vedere: Ultima (spero: o)) versione del punteggio del 2015

Ecco il nuovo file midi .

Prima versione BASH (tempo mancante)

Perché non ci ho pensato prima ...: o)

Sono 22 byte in meno rispetto ad AWK, per lo stesso risultato

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

Come la versione precedente in AWK, scrive su stdout un file di notazione "ABC" valido (grazie a Tobia per aver scoperto che l'istruzione "L" era facoltativa)

Sembra così: ultima versione della partizione "2015"

E suona esattamente come la versione precedente .

Versione precedente in AWK (86 byte)

Ecco una nuova versione; un po 'più a lungo, ma con un tempismo più preciso. Ho lasciato la prima versione sotto per confronto / riferimento:

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

Questo è ancora un file "abc" valido, che assomiglia a questo: punteggio del 2015

Ecco il nuovo file MIDI (ho accelerato il tempo per rimanere al di sotto del limite di 30 secondi).

Prima versione in AWK (66 byte):

Questo è molto meno interessante della mia precedente risposta , ma è molto più breve, quindi:

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

Questo genera un file "abc" valido, che può essere letto (tra gli altri) da EasyABC. Sarà simile a questo: Punteggio di "2015" in morse

e suonerà così (file midi) . +


Dovresti pubblicarlo come ABC senza il wrapping AWK e richiedere la generosità!
Tobia,

Tobia, ABC è un formato di file, non un linguaggio di programmazione. E finora con 86 byte questa è la risposta più breve ... La domanda ora è "il suono risultante è abbastanza vicino dai requisiti per la validità della risposta?"
LeFauve,

Lo avrei chiamato anche un formato di file, ma la pagina wiki collegata all'OP lo elenca come linguaggio di programmazione audio. Ho inserito il mio file ABC come voce, insieme a un programma Csound più appropriato. Vediamo cosa ne pensano.
Tobia,

Questo è il problema con i wiki ... a volte le persone che li modificano commettono errori: o). Molte cose diverse possono essere chiamate "linguaggi di programmazione", ma penso che ABC non sia uno di questi. Comunque, grazie per scoprire che la "L" era facoltativa. Mi ha salvato un paio di byte; o)
LeFauve il

"I segmenti lunghi devono essere almeno 3 volte più lunghi dei segmenti corti." L'ultima riga musicale visualizzata non soddisfa i requisiti.
mbomb007,

13

codice macchina x86 (file .COM): 121 120 113 109 byte

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

Può essere facilmente eseguito sotto DosBox; l'output è un file .SND denominato SND. Ecco una versione FLAC del suo output (e qui il file .COM).

Assemblaggio commentato:

    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:

Quanto data.datsopra incluso è una rappresentazione facile da usare della stringa morse (bit inferiore: suono acceso / suono spento, 7 bit superiori: lunghezza del suono nei campioni >> 4) generata da uno 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))

Non è necessariamente necessaria un'estensione di file, se ciò può farti risparmiare quattro byte.
Martin Ender,

4
@ MartinBüttner: in realtà, mi permette di salvare 3 byte. Il aof a.sndviene messo subito prima dell'intestazione SND, che inizia con .sndseguito da un byte zero, quindi ottengo la .sndparte gratuitamente e riciclo il suo terminatore zero. Inoltre, il fatto che l'intestazione inizi un byte dopo il nome del file mi consente di usare a inc dxper spostarmi nell'intestazione (1 byte) anziché in mov dx, header(3 byte). OTOH, se mi avessero permesso di chiamarlo da .sndsolo avrei potuto salvare due byte, ma non sono sicuro che il vero DOS lo avrebbe permesso (il trattamento dell'estensione sotto DOS era abbastanza singolare).
Matteo Italia,

Ho fatto alcuni test chiamando il file .SND: sono arrivato .SNDsu DosBox, SND~1su FreeDOS e mi aspetto qualcos'altro su DOS "reale"; quindi, è sicuramente un'area di "comportamento indefinito". Alla fine, ho deciso di chiamare il file SND(1 byte in meno a causa della rimozione a, mantenendo il costo del inc dx- che diventa 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
   ]
]

Giocare online


Oh, puoi anche usare la notazione infix per Export, come "m.mid"~Export~Sound@....
Martin Ender,

(b=None~s~#&)@.6dovrebbe (b=None~s~#&)@.4 anche essere possibile salvare 3 caratteri 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, ma c'era già un 0,2 in ogni pausa. .4 + .2
DavidC

@DavidCarraher Ah, hai ragione.
Martin Ender,

7

Perl 5: 94 122 140

I file SND hanno intestazioni più semplici, non è necessario stampare in binario. Questa versione produce un file SND mono da 8 kHz chiamato 'a':

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

Il file del risultato .

Vecchia soluzione Produce un file WAV mono da 1 kHz a 8 bit denominato "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

Il file del risultato .

Per arrivare a 122 caratteri ho dovuto incollare l'intestazione in binario invece di comprimerlo, il che rende il codice difficile da copiare qui. La versione con 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 Base64 della soluzione effettiva da 122 byte:

b3BlbgpBLCc+YSc7cHJpbnQKQSJSSUZGkEIAAFdBVkVmbXQgEAAAAAEAAQDoAwAA6AMAAAEACABk
YXRhbEIAACIscGFjayJzKiIsbWFweygkXyl4KDg5NDI2MTA3Mj4+JHYrKyYxPzQwMDoxMDApfSgy
NTUsMCl4MjA=

Potresti usare l' .auestensione, forse. Molto bene!
F. Hauri,

7

AWK: 172 170 byte

... e senza usare alcuna libreria 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}

Questo genera un file audio Sun au su stdout che può essere riprodotto da vlc (tra gli altri). Mentre au fileformat non ha alcuna limitazione della frequenza di campionamento, VLC si rifiuta di riprodurre qualsiasi file con una frequenza di campionamento inferiore a 4096 Hz, quindi ho usato questa frequenza

EDIT: collegamento al file audio risultante su DropBox


(*) Non dovrebbe esserci un bonus per questo? ; O)


Non hai bisogno dello spazio nella d=d "\177... concatenazione. Questo salva un byte. Ma quando riproduco il file audio risultante, sembra che manchi l'ultima parte del 5.
Mark Reed

Grazie. Ho salvato un secondo byte con un'altra concatenazione usando lo stesso trucco. Ho appena controllato il file audio con vlc 2.1.1 e sembra completo. Quale giocatore hai usato?
LeFauve,

Stavo usando QuickTime Player su OS X. L'ho aperto in VLC e suona bene, quindi non importa. Colpa di Apple, non tua.
Mark Reed,

7

Python, 155

Utilizza il modulo wave incorporato di 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

Scrive su un file chiamato n.

Grazie Sp3000 per il suggerimento sull'uso della comprensione dell'elenco per il ciclo (questo ha aiutato a rimuovere un po 'di rientro).

Ascoltalo:

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

Ecco un link a SoundCloud se il lettore incorporato non funziona per te.

Codice commentato:

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

Poiché wè un effetto collaterale, penso che puoi elencare comp per salvare due byte: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 ... non ci ho pensato = D. grazie!
Vectorizzato il

Questa potrebbe essere una domanda stupida, ma se h è diviso per 4 per ogni iterazione, come si ferma il ciclo while?
Derek 功夫 會 功夫

@Derek 朕 會 功夫 Per python, quando h diventa 0, viene valutato su False, terminando il ciclo. Il ciclo while è un trucco da golf per estrarre i valori nella sequenza "11333033333013333011111" uno per uno.
Vectorizzato il

@bitpwner Ho capito che 0 viene valutato come falso, ma non è così per tutti i numeri positivi, se lo dividi per un altro numero positivo, non puoi in alcun modo ottenere uno 0?
Derek 朕 會 功夫

6

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

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

Emette in un file denominato a.

Risultato ospitato su Dropbox

Codice non golfato:

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

Pitone 3 2, 191 188 174 171 (nessuna biblioteca)

I file wav sono incredibilmente semplici. Volevo provare senza librerie. Per qualche motivo i miei file sembrano arrestare in modo anomalo Windows Media Player. Tempo velocelavoribug a metà del file. La conversione a una frequenza di campionamento maggiore utilizzando Audition risolve questo problema.

Aggiornamento : implementate alcune ottimizzazioni dalla risposta Perl. Ora produce solo il nome ne il campionamento a 1000Hz. Informazioni modificate sopra di conseguenza.

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)

Vecchia versione

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 byte

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

Ed ecco l'output.

Versione leggibile,

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

Puoi salvare alcuni byte avvolgendo la tua classe nello spazio dei nomi System.Collections.Generic (che funziona davvero). Ci sono anche alcuni spazi bianchi non necessari che puoi rimuovere.
Programma FOX il

4

C # 382 333 byte

Non utilizza librerie non standard, scrive un wav di 8 bit per campione 44100 campioni al secondo, con quello che spero sia un'intestazione valida (sembra riprodursi / caricarsi felicemente in WMP / .NET / Audacity).

L'intestazione è codificata in base64 e il morse è codificato come segnale on / off che viene memorizzato in un singolo long (64 bit) perché gli ultimi 5 bit sono gli stessi del primo.

Il risultato può essere trovato qui

Codice golfizzato:

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

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

La sfida non richiede il nome del file con cui terminare .wav, quindi puoi salvare 4 byte lì.
Programma FOX

Bel modo di adattare il codice PWM a 69 bit in una costante a 64 bit. Stavo provando qualcosa del genere ma probabilmente non sono riuscito ad accorciare il mio codice usando il tuo metodo.
Nutki,

2

SuperCollider , 625 605 byte

Presentazione del linguaggio di programmazione audio!

L'output viene scritto in un file bin formato AIFF. Windows Media Player non riesce ad aprirlo, ma funziona bene in VLC media player. Il file generato aè un file 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;

Ho creato alcune funzioni di SuperCollider: fgenera un breve segnale acustico,g una breve pausa, hun lungo segnale acustico e iuna lunga pausa. SuperCollider ha bisogno delle posizioni iniziali per ogni onda sinusoidale e non di una lunghezza, quindi ho dovuto creare funzioni che generano un'onda con la posizione iniziale corretta e devo chiamare le funzioni ogni volta che ho bisogno di un'onda sinusoidale. (Non sono riuscito a memorizzare un'onda con una lunghezza specifica in una variabile da riutilizzare). La \wdefinizione viene creata alla fine del blocco di codice.

Sul mio computer Windows, non ha salvato il file audio nella stessa directory del mio codice, ma in questa directory:

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

Risultato ospitato su Dropbox

Codice con rientro:

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 è un linguaggio di programmazione audio. bitpwner mi ha aiutato a farlo scendere da 201 byte a 147 byte.

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

Ecco un link diretto a SoundCloud se il lettore incorporato non funziona per te.


1
Riuscito a ridurlo a 164 con un trucco simile usato nella mia risposta: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 Stai usando jper evitare l'array?
KSFT,

Il numero magico 1016835in binario è 11111000010000000011. jè lì semplicemente per tenere traccia delle pause tra ogni cifra di 2015(ogni cifra ha 5 suoni).
Vectorizzato il

@bitpwner Ah, non l'ho nemmeno notato. È davvero una bella idea!
KSFT,

Puoi modificarlo nella tua risposta per avere maggiori possibilità di ricompensa. imo, il miglioramento non è molto per giustificare una nuova risposta perché hai già fatto la maggior parte del lavoro per capire Chuck;)
Vectorized

2

Csound, 140 + 40 = 180

Linguaggio di programmazione audio.

Questo è il file dell'orchestra:

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

e questo è il file di punteggio:

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

Le dimensioni vengono calcolate supponendo che non vi siano spazi bianchi aggiuntivi, terminatore a riga singola (UNIX) e nessun terminatore dopo l'ultima riga.

Li invochi usando il comando csound:

csound morse.org morse.sco

che produrrà un file di output nella directory corrente, per impostazione predefinita denominato "test.aif"

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

Avrei potuto radere due o tre byte scegliendo una forma d'onda più brutta, ma mi piace il suono dell'onda sinusoidale tradizionale Morse.

PS: Sono un principiante assoluto a Csound, tutti i suggerimenti per il golf sono apprezzati, soprattutto per quanto riguarda il file dei punteggi!


Ah, non vedevo l'ora di CSound. Se nessuno ci avesse scritto una risposta, probabilmente avrei provato a scriverne una anch'io. :)
Martin Ender,

1

brainfuck , 649 byte

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

Questo genera una sequenza di campioni senza segno a 8 bit che possono essere riprodotti a 8000 campioni al secondo con uno strumento come aplay su Linux. Accredito alla tabella delle costanti BF .

Provalo online!

Un po 'meno golfato

DIT DIT DAH DAH DAH
++[>
 -[+>++[++<]>]>[>..........-..........+<-]
 -[+>++[++<]>]>[....................-]
<<<<<-]
+++[>
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
 -[+>++[++<]>]>[....................-]
<<<-]
-[+>++[++<]>]>[....................-]
DAH DAH DAH DAH DAH
+++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
+++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DAH DAH DAH DAH
-[+>++[++<]>]>[>..........-..........+<-]
++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DIT DIT DIT DIT
+++++[>
 -[+>++[++<]>]>[....................-]
 -[+>++[++<]>]>[>..........-..........+<-]
<<<<<-]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.