Morse das neue Jahr

33

Dies ist die wöchentliche Herausforderung Nr. 1. Thema: Audioverarbeitung

Ihre Aufgabe ist es, ein Programm zu schreiben, das eine Audiodatei auf eine Disc schreibt (in einem Format Ihrer Wahl), die den Morse-Code für enthält 2015, d. H

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

Sie können eine beliebige Art von Klang für die Segmente auswählen, z. B. eine Sinuswelle mit einer Frequenz, einen Akkord, Rauschen oder ein Instrument (z. B. mithilfe von MIDI-Dateien), sofern dies hörbar ist. Es gibt jedoch einige Einschränkungen für das Timing:

  • Kurze Segmente müssen mindestens 0,2 Sekunden lang sein.
  • Lange Segmente müssen mindestens dreimal so lang sein wie kurze Segmente.
  • Unterbrechungen zwischen Segmenten innerhalb einer Ziffer sollten genauso lang sein wie kurze Segmente.
  • Pausen zwischen den Ziffern sollten genauso lang sein wie lange Segmente.
  • Jedes Segment und jeder Bruch kann bis zu 10% von der durchschnittlichen Länge dieses Segments / Bruches abweichen.
  • Die gesamte Audiodatei darf nicht länger als 30 Sekunden sein.

Die Pausen müssen nicht ganz leise sein, aber die Morse-Segmente sollten hörbar lauter sein als die Pausen.

Beachten Sie, dass Sie haben eine Audiodatei zu schreiben. Sie können den Ton nicht einfach abspielen, z. B. mit Systemtönen. Sie können jede Art von Bibliothek verwenden, um das Dateiformat und die Audiogenerierung zu verwalten. Sie dürfen jedoch keine integrierten Funktionen für die Morsekodierung verwenden.

Dies ist Codegolf, daher gewinnt die kürzeste Antwort (in Bytes).

Überlegen Sie sich, ob Sie einen Link zu einem Upload der resultierenden Audiodatei (in SoundCloud oder ähnlichem) erstellen möchten, damit die Benutzer das Ergebnis überprüfen können, ohne Ihren Code ausführen zu müssen. Wenn Sie auf SoundCloud hochladen, müssen Sie das Herunterladen auf der Registerkarte "Berechtigungen" des Tracks aktivieren.

Wenn Ihre Ausgabe ein eher ungewöhnliches Dateiformat verwendet, fügen Sie einige Informationen zum Wiedergeben und / oder Konvertieren in ein gängigeres Format hinzu und laden Sie es hoch.

Beispielstrecke

Dies ist eine manuell erzeugte Beispielspur, die der Spezifikation entspricht und für die Morse-Segmente Rauschen verwendet (genauer gesagt Mikrofon-Hintergrundrauschen). Hier ist ein Link zu SoundCloud, falls der eingebettete Player für Sie nicht funktioniert.

Kopfgeld-Details

Ich werde die Prämie für die kürzeste Einsendung in einer Audio-Programmiersprache vergeben , dh einer Sprache, die zur Synthese von Ton entwickelt wurde. Diese Liste ist nicht vollständig. Sie können daher auch eine andere Audio-Programmiersprache verwenden, sofern Sie eine kennen. Wenn Sie nicht sicher sind, ob eine Sprache, die Sie verwenden möchten, als Audio-Programmiersprache klassifiziert ist, lassen Sie es mich bitte in den Kommentaren oder im Chat wissen , und wir können darüber diskutieren.

Beachten Sie, dass Ihre Einreichung immer noch allen Regeln entsprechen muss - insbesondere muss sie eine Datei schreiben, die möglicherweise nicht in allen Audio-Programmiersprachen möglich ist. Zum Beispiel kann gibber , soweit ich das beurteilen kann, den Sound nur abspielen und nicht in einer Datei speichern.

Martin Ender
quelle
1
Zusätzliche Herausforderung: Lass es wirklich schön klingen.
Kaz Wolfe
6
@Mew Wie schön kann Morse evtl. klingen?
Martin Ender
1
Dies in Brainf ** k zu tun, würde das auf so vielen Bonuslevels großartig machen.
Mast
@Mast Wahrscheinlich, aber leider kann BF nicht in eine Datei schreiben. ;) (Ich werde beim nächsten Mal
Martin Ender
Werden Musiknotationsformate, die nur die Partitur und kein Audio (.mid, .abc, siehe unten) enthalten, als "Audiodatei" akzeptiert? Was ist mit "Tracker" -Formaten, die sowohl Samples als auch eine Partitur enthalten, aber keine gerenderten Audiotracks (.mod, .xm)?
Tobia

Antworten:

4

AWK BASH: 66 86 67 74 Bytes

Wie von Martin Büttner gewünscht, habe ich ein Tempo hinzugefügt, da es nach Überprüfung des ABC-Notationsstandards keinen definierten Standardwert dafür zu geben scheint (danke nutki, dass Sie darauf hingewiesen haben).
Ich schreibe auch in eine Disk-Datei (a) anstelle von STDOUT, da die Frage explizit "eine Datei auf Disk" wollte.

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

Ich habe ein Tempo von 99 eingestellt, wodurch die Audiodatei 22 Sekunden hält. Es ist langsamer als meine Vorgängerversion, aber jetzt sollte es auf jedem ABC-Spieler die gleiche Länge haben und unter 30 Sekunden passen.

Es sieht ... sehr nach der vorherigen Version aus, wie Sie sehen können: Letzte (ich hoffe: o)) Version der Punktzahl von 2015

Hier ist die neue Midi-Datei .

Erste BASH-Version (Tempo fehlt)

Warum habe ich nicht zuerst daran gedacht ...: o)

Das sind 22 Bytes weniger als bei AWK, bei gleichem Ergebnis

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

Wie die Vorgängerversion in AWK schreibt es auf stdout eine gültige "ABC" -Notationsdatei (danke Tobia, dass sie herausgefunden hat, dass die "L" -Anweisung optional war)

Es sieht aus wie das: letzte Version von "2015" Partition

Und es klingt genauso wie in der Vorgängerversion .

Vorherige Version in AWK (86 Bytes)

Hier ist eine neue Version; etwas länger, aber mit genauerem Timing. Ich lasse die erste Version unten zum Vergleich / Referenz:

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

Dies ist immer noch eine gültige "abc" -Datei, die so aussieht: Ergebnis von 2015

Hier ist die neue Midi-Datei (ich habe das Tempo beschleunigt, um unter der 30-Sekunden-Grenze zu bleiben).

Erste Version in AWK (66 Bytes):

Dies ist viel weniger interessant als meine vorherige Antwort , aber es ist viel kürzer, also:

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

Dies gibt eine gültige "abc" -Datei aus, die (unter anderem) in EasyABC eingelesen werden kann. Es wird so aussehen: Ergebnis von "2015" in morse

und es wird so klingen (Midi-Datei) . +

LeFauve
quelle
Sie sollten es als ABC ohne die AWK Verpackung bekannt geben und die Prämie fordern!
Tobia
Tobia, ABC ist ein Dateiformat, keine Programmiersprache. Und bis jetzt ist dies mit 86 Bytes die kürzeste Antwort ... Die Frage lautet nun "Entspricht der resultierende Klang den Anforderungen, damit die Antwort gültig ist?".
LeFauve,
Ich hätte es auch ein Dateiformat genannt, aber die Wiki-Seite, mit der das OP verlinkt ist, listet es als Sound-Programmiersprache auf. Ich habe meine eigene ABC-Datei als Eintrag zusammen mit einem korrekteren Csound-Programm angegeben. Mal sehen, was sie davon halten.
Tobia
Das ist das Problem mit Wikis ... manchmal machen die Leute, die sie bearbeiten, Fehler: o). Viele verschiedene Dinge können als "Programmiersprachen" bezeichnet werden, aber ich denke, ABC ist keine davon. Trotzdem, danke, dass du herausgefunden hast, dass das "L" optional war. Es hat mir ein paar Bytes erspart; o)
LeFauve
"Lange Segmente müssen mindestens dreimal so lang sein wie kurze Segmente." Die zuletzt angezeigte Musikzeile entspricht nicht den Anforderungen.
mbomb007
13

x86-Maschinencode (COM-Datei): 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

Kann problemlos unter DosBox ausgeführt werden; Die Ausgabe ist eine .SND-Datei mit dem Namen SND. Hier ist eine FLAC-Version der Ausgabe (und hier die .COM-Datei).

Kommentierte Versammlung:

    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:

Das data.datobige Beispiel ist eine benutzerfreundliche Darstellung der Morsezeichenfolge (unteres Bit: Ton ein / Ton aus, obere 7 Bits: Tonlänge in Samples >> 4), die von einem Python-Skript generiert wurde:

#!/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
quelle
Sie brauchen nicht unbedingt eine Dateierweiterung, wenn Sie dadurch vier Bytes sparen können.
Martin Ender
4
@ MartinBüttner: eigentlich kann ich damit 3 bytes sparen. Das aof a.sndwird direkt vor den SND-Header gestellt, der mit .sndeinem Null-Byte beginnt , sodass ich das .sndTeil kostenlos bekomme und dessen Null-Terminator wieder verwende. Die Tatsache, dass der Header ein Byte nach dem Dateinamen beginnt, ermöglicht es mir außerdem, a zu verwenden inc dx, um zum Header (1 Byte) anstelle von a mov dx, header(3 Byte) zu wechseln . OTOH, wenn ich es nur .sndalleine nennen dürfe, könnte ich zwei Bytes sparen, aber ich bin nicht sicher, ob das unter DOS möglich ist (die Behandlung der Erweiterung unter DOS war ziemlich eigenartig).
Matteo Italia
Ich habe einige Tests mit dem Aufrufen der Datei durchgeführt .SND: Ich bin .SNDauf DosBox und SND~1FreeDOS gelandet und erwarte auf "echtem" DOS etwas anderes. Somit ist es definitiv ein Bereich "undefinierten Verhaltens". Am Ende entschied ich mich dafür, die Datei aufzurufen SND(1 Byte weniger aufgrund des Entfernens a, wobei die Kosten für das inc dx-, was wird, beibehalten werden 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]
   ]
]

Online spielen

Swish
quelle
Oh, Sie können auch die Infix-Notation für verwenden Export, wie "m.mid"~Export~Sound@....
Martin Ender
(b=None~s~#&)@.6sollte auch sein (b=None~s~#&)@.4 , können Sie 3 Zeichen mit 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]]
speichern
Martin, aber in jeder Pause gab es schon eine .2. .4 + .2
DavidC
@ DavidCarraher Ah, du hast recht.
Martin Ender
7

Perl 5: 94 122 140

SND-Dateien haben einfachere Header und müssen nicht binär gedruckt werden. Diese Versionen erzeugen eine 8-kHz-Mono-SND-Datei mit dem Namen 'a':

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

Das Ergebnis Datei .

Alte Lösung. Erzeugt eine 1-kHz-8-Bit-Mono-WAV-Datei mit dem Namen '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

Das Ergebnis Datei .

Um 122 Zeichen zu erhalten, musste ich den Header in eine Binärdatei einfügen, anstatt ihn zu packen, was das Kopieren des Codes hier erschwert. Die entkommene Version ist:

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-Codierung der aktuellen 122-Byte-Lösung:

b3BlbgpBLCc+YSc7cHJpbnQKQSJSSUZGkEIAAFdBVkVmbXQgEAAAAAEAAQDoAwAA6AMAAAEACABk
YXRhbEIAACIscGFjayJzKiIsbWFweygkXyl4KDg5NDI2MTA3Mj4+JHYrKyYxPzQwMDoxMDApfSgy
NTUsMCl4MjA=
nutki
quelle
.auDu könntest vielleicht eine Erweiterung gebrauchen . Gut gemacht!
F. Hauri
7

AWK: 172 170 Bytes

... und ohne Wave-Bibliothek! (*)

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}

Dadurch wird eine Sun au-Audiodatei auf stdout ausgegeben, die unter anderem von vlc wiedergegeben werden kann. Während das Dateiformat au keine Einschränkung der Abtastrate aufweist, lehnt VLC die Wiedergabe von Dateien mit einer Abtastrate von weniger als 4096 Hz ab. Deshalb habe ich diese Frequenz verwendet

BEARBEITEN: Link zur resultierenden Audiodatei auf DropBox


(*) Sollte es dafür keinen Bonus geben? ;O)

LeFauve
quelle
Sie brauchen keinen Platz in der d=d "\177... Verkettung. Das spart ein Byte. Aber wenn ich die resultierende Audiodatei abspiele, klingt es so, als würde der letzte Punkt der 5. fehlen.
Mark Reed
Vielen Dank. Ich habe mit demselben Trick ein zweites Byte mit einer anderen Verkettung gespeichert. Ich habe gerade die Audiodatei mit vlc 2.1.1 überprüft und es klingt komplett. Welchen Player hast du benutzt?
LeFauve
Ich habe QuickTime Player unter OS X verwendet. Ich habe es in VLC geöffnet und es hört sich gut an. Apples Schuld, nicht deine.
Mark Reed
7

Python, 155

Verwendet das in Python integrierte Wave-Modul.

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

Schreibt in eine Datei mit dem Namen n.

Vielen Dank an Sp3000 für den Vorschlag zur Verwendung des Listenverständnisses für die Schleife (dies hat dazu beigetragen, ein wenig Einrückung zu entfernen).

Hör es dir an:

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

Hier ist ein Link zu SoundCloud, falls der eingebettete Player für Sie nicht funktioniert.

Kommentierter Code:

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
Vektorisiert
quelle
Da wist ein Nebeneffekt, ich denke, Sie können comp while h:[w(h%4*chr(i%99))for i in range(h%2*k)];w((2-h%2)*k*" ");h/=4
auflisten
@ Sp3000 oo ... habe nicht daran gedacht = D. Danke!
Vectorized
Dies mag eine dumme Frage sein, aber wenn h für jede Iteration durch 4 geteilt wird, wie stoppt die while-Schleife?
Derek 朕 朕 功夫
@Derek 朕 會 會 Wenn für Python h 0 wird, wird es zu False ausgewertet, wodurch die Schleife beendet wird. Die while-Schleife ist ein Golftrick, mit dem die Werte in der Reihenfolge "11333033333013333011111" nacheinander extrahiert werden.
Vectorized
@bitpwner Ich verstehe, dass 0 falsch ist, aber ist es nicht so, dass für alle positiven Zahlen, wenn Sie es durch eine andere positive Zahl teilen, es keine Möglichkeit gibt, eine 0 daraus zu bekommen?
Derek 朕 朕 功夫
6

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

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

Ausgabe in eine Datei mit dem Namen a.

Ergebnis auf Dropbox gehostet

Ungolfed-Code:

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
quelle
5

Python 3 2, 191 188 174 171 (keine Bibliotheken)

WAV-Dateien sind unglaublich einfach. Wollte mal ohne Bibliotheken probieren. Aus irgendeinem Grund scheinen meine Dateien Windows Media Player zum Absturz zu bringen. Schnelle ZeitfunktioniertBugs auf halbem Weg in die Datei. Die Umstellung auf eine höhere Samplerate mit Audition behebt dieses Problem.

Update : Einige Optimierungen aus der Perl-Antwort implementiert. Jetzt nur noch mit dem Namen nund in 1000Hz Abtastung ausgeben. Info oben entsprechend bearbeitet.

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)

Alte Version

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
quelle
4

C # ~ 485 Bytes

Verwenden der Wav.Net- Bibliothek.

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

Und hier ist die Ausgabe.

Lesbare Version,

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
quelle
Sie können einige Bytes sparen, indem Sie Ihre Klasse in den Namespace System.Collections.Generic einschließen (das funktioniert tatsächlich). Es gibt auch einige unnötige Leerzeichen, die Sie entfernen können.
ProgramFOX
4

C # 382 333 Byte

Verwendet keine nicht-standardmäßigen Bibliotheken, schreibt ein 8 Bit pro Sample 44100 Samples pro Sekunde WAV mit, was ich hoffe, ist ein gültiger Header (scheint in WMP / .NET / Audacity glücklich zu spielen / zu laden).

Der Header ist Base64-codiert, und die Morse wird als Ein- / Ausschaltsignal codiert, das in einer einzelnen Länge (64 Bit) gespeichert wird, da die letzten 5 Bit mit den ersten identisch sind.

Das Ergebnis finden Sie hier

Golf Code:

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

Mit Kommentaren:

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
quelle
Die Herausforderung erfordert nicht, dass der Name der Datei endet .wav, sodass Sie dort 4 Bytes speichern können.
ProgramFOX
Gute Möglichkeit, den 69-Bit-PWM-Code in eine 64-Bit-Konstante einzufügen. Ich habe so etwas versucht, aber wahrscheinlich konnte ich meinen Code mit Ihrer Methode nicht verkürzen.
Nutki
2

SuperCollider , 625 605 Bytes

Einreichung der Audio-Programmiersprache!

Die Ausgabe wird in eine Datei bim AIFF-Format geschrieben. Windows Media Player kann es nicht öffnen, aber es funktioniert einwandfrei in VLC Media Player. Die erzeugte Datei aist eine OSC-Datei .

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;

Ich habe einige SuperCollider-Funktionen erstellt: fErzeugt einen kurzen Piepton, geine kurze Pause, heinen langen Piepton und ieine lange Pause. SuperCollider benötigt die Startpositionen für jede Sinuswelle und keine Länge. Deshalb musste ich Funktionen erstellen, die eine Welle mit der richtigen Startposition erzeugen, und ich muss die Funktionen jedes Mal aufrufen, wenn ich eine Sinuswelle benötige. (Ich konnte eine Wave mit einer bestimmten Länge nicht in einer Variablen speichern, um sie wiederzuverwenden.) Die \wDefinition wird am Ende des Codeblocks erstellt.

Auf meinem Windows-Computer wurde die Audiodatei nicht im selben Verzeichnis wie mein Code gespeichert, sondern in diesem Verzeichnis:

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

Ergebnis auf Dropbox gehostet

Code mit Einrückung:

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
quelle
2

ChucK - 1195 217 201 147 145 144

ChucK ist eine Audio-Programmiersprache. bitpwner hat mir geholfen, dies von 201 Bytes auf 147 Bytes zu reduzieren.

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

Hier ist ein direkter Link zu SoundCloud, falls der eingebettete Player für Sie nicht funktioniert.

KSFT
quelle
1
Es gelang mir, es mit einem ähnlichen Trick, der in meiner Antwort verwendet wurde, auf 164 zu reduzieren: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 Verwenden Sie j, um das Array zu vermeiden?
KSFT
Die magische Zahl 1016835im Binär ist 11111000010000000011. jist dazu da, einfach die Pausen zwischen jeder Ziffer zu verfolgen 2015(jede Ziffer hat 5 Töne).
Vectorized
@bitpwner Ah, das habe ich gar nicht gemerkt. Das ist eine wirklich coole Idee!
KSFT
Sie können es in Ihre Antwort ändern, um eine höhere Chance auf Kopfgeld zu haben. imo, die Verbesserung ist nicht viel, um eine neue Antwort zu rechtfertigen, da Sie bereits den Großteil der Arbeit getan haben, um Chuck herauszufinden;)
Vectorized
2

Csound, 140 + 40 = 180

Audio-Programmiersprache.

Dies ist die Orchesterdatei:

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

und das ist die Score-Datei:

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

Die Größen werden unter der Annahme berechnet, dass kein zusätzliches Leerzeichen, ein einzeiliger Abschluss (UNIX) und kein Abschluss nach der letzten Zeile vorhanden sind.

Sie rufen sie mit dem Befehl csound auf:

csound morse.org morse.sco

Dadurch wird im aktuellen Verzeichnis eine Ausgabedatei mit dem Namen "test.aif" erstellt.

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

Ich hätte zwei oder drei Bytes rasieren können, indem ich eine hässlichere Wellenform gewählt hätte, aber ich mag den Klang der traditionellen Morse-Sinus-Welle.

PS: Ich bin ein absoluter Neuling bei Csound, alle Golftipps sind willkommen, vor allem was die Punktedatei betrifft!

Tobia
quelle
Ah, ich freute mich auf CSound. Wenn niemand eine Antwort darauf gepostet hätte, hätte ich wahrscheinlich versucht, selbst eine zu schreiben. :)
Martin Ender
1

Brainfuck , 649 Bytes

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

Dies erzeugt eine Sequenz von 8-Bit-Samples ohne Vorzeichen, die mit einem Tool wie aplayLinux mit 8000 Samples pro Sekunde abgespielt werden können . Gutschrift auf Tabelle der BF-Konstanten .

Probieren Sie es online!

Etwas weniger golfen

DIT DIT DAH DAH DAH
++[>
 -[+>++[++<]>]>[>..........-..........+<-]
 -[+>++[++<]>]>[....................-]
<<<<<-]
+++[>
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
 -[+>++[++<]>]>[....................-]
<<<-]
-[+>++[++<]>]>[....................-]
DAH DAH DAH DAH DAH
+++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
+++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DAH DAH DAH DAH
-[+>++[++<]>]>[>..........-..........+<-]
++++[>
 -[+>++[++<]>]>[....................-]
 +++[>
  -[+>++[++<]>]>[>..........-..........+<-]
 <<<-]
<<<-]
++[>
 -[+>++[++<]>]>[....................-]
<<<-]
DIT DIT DIT DIT DIT
+++++[>
 -[+>++[++<]>]>[....................-]
 -[+>++[++<]>]>[>..........-..........+<-]
<<<<<-]
Ceilingcat
quelle