Der Klang der Worte

11

Die Leute haben viele Dinge geschrieben, die es ermöglichen, eine Sache als eine andere zu visualisieren. Jetzt schlage ich vor, Briefe in Musik übersetzen zu können! Es ist Ihre Aufgabe, ein Programm zu schreiben, das eine Textdatei verwendet und eine Audiodatei ausgibt, wobei jeder Buchstabe in eine bestimmte Notiz von konvertiert wird C3-C8.

Haftungsausschluss - Ich erwarte eigentlich nicht, dass die Musik gut klingt, aber ich hoffe, überrascht zu sein.

Spezifikationen

  • Sie nehmen den Namen einer Datei als Zeichenfolge und den BPM (Beats per Minute) als Int
  • Sie machen Großbuchstaben Azur NotizC3
  • Und gehen Sie für jeden Charakter in dieser Reihenfolge einen halben Schritt nach oben: ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
  • Ja, nicht jedes Zeichen wird verwendet, da dies zu viele Oktaven umfasst.
  • Sie übersetzen jedes Zeichen in der Datei auf diese Weise
  • Fügen Sie die Noten zum angegebenen BPM als Viertelnoten zusammen
  • Entweder als Sounddatei speichern (ich vermute, Midi ist am einfachsten, aber alles ist in Ordnung) oder abspielen
  • Jedes vernünftige Eingabeformat ist in Ordnung
  • Keine Standardlücken
  • Dies ist Code-Golf, also gewinnt der kürzeste Code in Bytes !

Boni

  • Transponieren der Ausgabe zulassen - 50 Bytes
  • Ermöglichen Sie die Überlagerung mehrerer Spuren, indem Sie mehrere Dateien aufnehmen - 75 Byte
  • Verbinden Sie aufeinanderfolgende Buchstaben zu einer längeren Note - 50 Bytes

Edit: Wow, wir haben negative Ergebnisse. Ich werde den Gewinner am Samstag bekannt geben.

Maltysen
quelle
Wann werden Sie den Gewinner bestimmen?
LegionMammal978
Können wir davon ausgehen, dass die Eingabe keine nicht aufgelisteten Zeichen enthält? Oder was sollen wir tun, wenn wir auf nicht aufgeführte Charaktere stoßen?
Apsiller
@apsillers Im Handumdrehen ! Antwort, sagte er, dass er undefiniertes Verhalten zulassen würde.
LegionMammal978
Ich habe ein Beispiel hochgeladen. Sie waren ganz richtig, es klingt wirklich nicht gut ...
Sanchises

Antworten:

6

MATLAB, 159-50-50-75 = -16

Beispieleingabe

Beispielausgabe

Erzeugt reine Sinus-Schallwellen, sehr funky (Sägezahn ist ebenfalls möglich, mit einer noch besseren Punktzahl, aber das klingt ein bisschen ... zu funky). Funktioniert als Funktion und erwartet daher ein Zeichenarray ( ['abc';'def']) mit einer Zeile pro 'Spur'. Ich denke, das wird unter "jedem vernünftigen Eingabeformat" behandelt , aber wenn der allgemeine Konsens darin besteht, dass ich eine Datei lesen muss, kann ich sie wahrscheinlich ändern. Eingabe isind Textspuren (von gleicher Länge), bBeats pro Minute und tTransponierung (Versorgung 0 für nicht transponiert). Es verschmilzt zwei Sinusse zu einem, indem die Sinus-Eingabe ausgeglichen wird, sodass ich alle drei Boni erhalten habe, was mir eine negative Punktzahl gibt.

function v(i,b,t)
s=0;for r=1:size(i)
o=[];for k=i(r,:)
o=cat(2,o,sin(55*pi*2^((k-28+t)/12)*(numel(o)/2^13+(0:1/2^13:60/b))));end
s=s+o;end
sound(s/max(s))
end

Version mit Eingabedatei: 211-175 = 36

Das Eingabeargument irepräsentiert jetzt den Dateinamen, andere Parameter bleiben unverändert. Funktioniert textreadmöglicherweise nicht mit neueren Versionen, da ich eine Warnung erhalte, die möglicherweise bald veraltet ist. BEARBEITEN: Text lesen wird anscheinend automatisch in Leerzeichen aufgeteilt, also habe ich das behoben. Ich glaube auch, dass ich versehentlich einige Außerirdische mit den seltsamen Geräuschen kontaktiert habe, die beim Testen erzeugt wurden.

function v(i,b,t)
i=textread(i,'%s','whitespace','','delimiter','\n');s=0;for r=1:size(i)
o=[];for k=i{r,:}
o=cat(2,o,sin(55*pi*2^((k-28+t)/12)*(numel(o)/2^13+(0:1/2^13:60/b))));end
s=s+o;end
sound(s/max(s))
end

Welche Version bevorzugen Sie? :) :)

Sanchises
quelle
Nun, die Spezifikation sagt ausdrücklich, die Eingabe aus einer Datei zu nehmen ...
LegionMammal978
@ LegionMammal978 Wenn Sie darauf bestehen: .matDateien haben ein vernünftiges Eingabeformat. Erstellen Sie eine .mat-Datei mit einer 'i'-Variablen, die Ihren Text enthält. Fügen Sie dann load(i);am Anfang von Zeile 2 der Top-Version hinzu. Punktzahl: -16 + 8 = -8. Ich werde dies tun, wenn Ihr Kommentar mehr positive Stimmen erhält als meiner, oder wenn das OP eine Meinung hat :)
Sanchises
4

Schnapp ! - 401 - 75 = 326

Probieren Sie es hier online aus.

Ich verwende diese Methode zum Zählen von Bytes für das Programm.

Geben Sie hier die Bildbeschreibung ein

Ich habe hinzugefügt, mehrere Sounds gleichzeitig abzuspielen.

Die Grundstruktur ist die gleiche wie beim Original (siehe unten), jedoch mit dem Zusatz von launch{}. launch{}Startet einen neuen Thread mit dem darin enthaltenen Code, wodurch Parallelität ermöglicht wird.

Der Code als Text lautet:

set[c v]to[ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
set[l v]to(list>
ask[BPM]and wait
set tempo to(answer)bpm
repeat until<(answer)=[
ask[notes]and wait
add(answer)to(l
end
delete(last v)of(l
for each(i)of(l
launch{
repeat(length of(i))(#
play note(i(c)(letter(#)of(i)))for(0.25)beats

(i(h)(n))
report(call(JavaScript function ([h][n]) {[return h.indexOf(n)+48]})with inputs(h)(n

Originalcode, 308.

Geben Sie hier die Bildbeschreibung ein

Lucky Snap! hat MIDI eingebaut .;)

Leider hat es keine indexOfFunktion, so dass ich einen externen JavaScript-Aufruf machen muss, was ziemlich teuer ist.

Der repeat () (#)Block stammt aus der Iterationsbibliothek.

Der Code kann als solcher Text geschrieben werden, so bekomme ich 308 Bytes:

set[c v]to[ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
ask[BPM]and wait
set tempo to(answer)bpm
ask[notes]and wait
repeat(length of(answer))(#)
play note(i(c)(letter(#)of(answer)))for(0.25)beats

(i(h)(n))
report(call(JavaScript function ([h][n]) {[return h.indexOf(n)+48]})with inputs(h)(n
Scimonster
quelle
Verfügt SNAP über eine Sammlung / Präsentation, zu der Sie diese hinzufügen können, wie es Scratch tut? Eine direkte Verknüpfung mit einer ausführbaren Version wäre IMO praktisch.
Geobits
Ja. Ich habe meinem Projekt einen Link hinzugefügt. Gute Idee. :)
Scimonster
Ignoriert es -1von indexOf? Im Moment sieht es so aus, als ob es nicht in der Saite ist, es macht Midi Nummer 47.
Maltysen
@Maltysen Die Frage sagt nie, was mit Eingaben außerhalb des richtigen Bereichs zu tun ist.
Scimonster
Wahr. Ich wollte, dass es ignoriert wird, aber da ich denke, dass es meine Schuld ist, dass ich nicht spezifisch genug bin, werde ich es zulassen.
Maltysen
4

Mathematica, 219 - 50 - 75 - 50 = 44

c=CharacterRange;d=Import;EmitSound[Function[b,Sound[Split@Characters@d@b/.a:{__String}:>SoundNote[StringPosition[c["A","Z"]<>" ()-,;.'\""<>c["a","z"],a[[1]]][[1,1]]+#3-12,60Length@a/#2],{0,60StringLength@d@b/#2}]]/@#]&

Nimmt die Liste der Eingabedateien, des BPM und der Anzahl der zu transponierenden Halbschritte als Eingabe und spielt den Sound ab (von einem Klavier würde jedes andere Instrument mehr Bytes benötigen.) Klingt nicht so schlecht!

LegionMammal978
quelle
1

JavaScript (ES6) 377 - 50 - 50 - 75 = 202

Hier ist zunächst ein ausführbares Snippet, das <input>Felder anstelle von Dateilesungen verwendet :

<b>BMP:</b> <input id="bpm" size=3 placeholder="BMP" value="120"> <b>Transpose:</b> <input size=3 id="transpose" placeholder="Transpose" value="0"><br/><br/><div id="tracks" style="float:left;padding-right:5px;"><input placeholder="Track" class="track"></div><button id="add">Add Additional Track</button><div style="clear:both; padding-top:5px;"></div><button id="play"><b>Play</b></button><script>f=function(s,b,z){C=new (window.AudioContext||window.webkitAudioContext);b=6e4/b;s.map(function(p){var o=C.createOscillator(t=setTimeout);o.connect(C.destination);o.start();p.split("").map(function(c,i){t(function(){o.frequency.value=440*Math.pow(2, ("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12)},b*i)});t(function(){o.stop()},p.length*b)})};document.getElementById("play").onclick=function(){f([].map.call(document.getElementsByClassName("track"),function(e){return e.value;}),+document.getElementById("bpm").value,+document.getElementById("transpose").value);};document.getElementById("add").onclick=function(){var i=document.createElement("input");i.placeholder="Track";i.className="track";document.getElementById("tracks").appendChild(document.createElement("br"));document.getElementById("tracks").appendChild(i);};</script>

Und jetzt der eigentliche Eintrag:

f=(n,b,z)=>{C=new AudioContext;b=6e4/b;s=n.map(m=>(x=new XMLHttpRequest,x.open("GET",m,0),x.send(),x.responseText));s.map(p=>{var o=C.createOscillator(t=setTimeout);o.connect(C.destination);o.start();[...p].map((c,i)=>t(_=>o.frequency.value=440*Math.pow(2,("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12),b*i)),t(_=>o.stop(),p.length*b)})}

Die drei Argumente sind ein Array von Dateipfad-Zeichenfolgen, die gleichzeitig abgespielt werden sollen, Noten pro Minute und die Anzahl der Halbschritte, um alle Eingaben zu transponieren.

Mit Leerzeichen und Kommentaren:

f=(n,b,z)=>{
    C=new AudioContext;
    b=6e4/b;

    // fill s with the contents of each file
    s = n.map(m=>(x=new XMLHttpRequest,x.open("GET",m,0),x.send(),x.responseText));

    // play each track
    s.map(p=>{
        var o=C.createOscillator(t=setTimeout);
        o.connect(C.destination);
        o.start();

        // queue up each note with setTimeout
        [...p].map((c,i)=>
            t(_=>
                o.frequency.value=440*
                    Math.pow(2,
                            ("ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'\"abcdefghijklmnopqrstuvwxyz".indexOf(c)-21+z)/12
                    ),
             b*i)
        );
        // queue up termination of those track
        t(_=>o.stop(),p.length*b)})
}

f(["file:///home/users/apsillers/notes.txt",
   "file:///home/users/apsillers/notes2.txt"],
  240, 5)
Apsiller
quelle