Le son des mots

11

Les gens ont écrit beaucoup de choses permettant de visualiser une chose comme une autre. Maintenant je propose de pouvoir traduire des lettres en musique! C'est votre travail d'écrire un programme qui prend un fichier texte et génère un fichier son avec chaque lettre convertie en une note spécifique C3-C8.

Avertissement - Je ne m'attends pas vraiment à ce que la musique sonne bien, mais j'espère être surpris.

Caractéristiques

  • Vous prenez le nom d'un fichier comme une chaîne et le BPM (battements par minute) comme un int
  • Vous mettez Aen majuscule pour être la noteC3
  • Et montez d'un demi-pas pour chaque personnage dans cet ordre: ABCDEFGHIJKLMNOPQRSTUVWXYZ ()-,;.'"abcdefghijklmnopqrstuvwxyz
  • Oui, tous les personnages ne seront pas utilisés car ils s'étendent sur trop d'octaves.
  • Vous traduisez ainsi chaque caractère du fichier
  • Regroupez les notes au BPM donné sous forme de noires
  • Soit enregistrer en tant que fichier son (je suppose que midi sera le plus simple, mais tout va bien) ou jouer
  • Tout format d'entrée sain est correct
  • Aucune échappatoire standard
  • C'est le code-golf, donc le code le plus court en octets gagne!

Bonus

  • Autoriser la transposition de la sortie - 50 octets
  • Autoriser la superposition de plusieurs pistes les unes sur les autres en prenant plusieurs fichiers - 75 octets
  • Joignez des lettres consécutives en une seule note plus longue - 50 octets

Edit: Wow, nous avons des scores négatifs. J'annoncerai le gagnant samedi.

Maltysen
la source
Quand déciderez-vous du gagnant?
LegionMammal978
Pouvons-nous supposer que l'entrée ne contiendra aucun caractère non répertorié? Ou, que devons-nous faire lorsque nous rencontrons des personnages non répertoriés?
apsillers
@apsillers In the Snap ! réponse, il a dit qu'il autoriserait un comportement indéfini.
LegionMammal978
J'ai téléchargé un échantillon; vous aviez tout à fait raison, ça ne sonne vraiment pas bien ...
Sanchises

Réponses:

6

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

Exemple d'entrée

Exemple de sortie

Génère des ondes sonores sinusoïdales pures, très funky (en dents de scie est également possible, avec un score encore meilleur, mais ça sonne un peu ... trop funky). Fonctionne comme une fonction, attend donc un tableau de caractères ( ['abc';'def']) avec une ligne par «piste». Je pense que cela est couvert par «tout format d'entrée sain» , mais si le consensus général est que j'ai besoin de lire un fichier, je suppose que je peux le changer. L'entrée iest des pistes de texte (d'égale longueur), des bbattements par minute et ttransposés (fournir 0 pour les non transposés). Il mélange deux sinus en un en compensant l'entrée du sinus, j'ai donc obtenu les trois bonus, me donnant un score négatif.

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 utilisant le fichier d'entrée: 211-175 = 36

L'argument d'entrée ireprésente désormais le nom du fichier, les autres paramètres étant inchangés. Peut ne pas fonctionner sur les versions plus récentes, car je reçois un avertissement qui textreadpourrait bientôt être obsolète. EDIT: textread se divise apparemment automatiquement aux espaces blancs, donc j'ai corrigé cela. De plus, je pense que j'ai peut-être accidentellement contacté des extraterrestres avec les sons étranges émis lors des tests.

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

Quelle version préférez-vous? :)

Sanchises
la source
Eh bien, la spécification dit explicitement de prendre l'entrée d'un fichier ...
LegionMammal978
@ LegionMammal978 Si vous insistez: les .matfichiers ont un format d'entrée sain. Créez un fichier .mat avec une variable «i» contenant votre texte. Ensuite, ajoutez load(i);au début de la ligne 2 de la version supérieure. Score: -16 + 8 = -8. Je le ferai lorsque votre commentaire aura plus de votes positifs que le mien, ou lorsque le PO aura une opinion :)
Sanchises
4

Snap ! - 401 - 75 = 326

Essayez-le en ligne ici.

J'utilise cette méthode de comptage d'octets pour le programme.

entrez la description de l'image ici

J'ai ajouté jouer plusieurs sons à la fois.

La structure de base est la même que l'original (voir ci-dessous), mais avec l'ajout de launch{}. launch{}démarre un nouveau thread avec le code à l'intérieur, permettant la simultanéité.

Le code sous forme de texte est:

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

Code d'origine, 308.

entrez la description de l'image ici

Lucky Snap! a un jeu MIDI intégré.;)

Malheureusement, il n'a pas de indexOffonction, donc je dois faire un appel JavaScript externe, ce qui est assez cher.

Le repeat () (#)bloc provient de la bibliothèque d'itérations.

Le code peut être écrit sous forme de texte comme celui-ci, c'est ainsi que j'obtiens 308 octets:

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
la source
Est-ce que SNAP a une collection / vitrine à laquelle vous pouvez ajouter comme Scratch? Lier directement à une version exécutable serait une OMI pratique.
Geobits
Oui. J'ai ajouté un lien vers mon projet. Bonne idée. :)
Scimonster
Ignore - -1de indexOf? En ce moment, il semble que si ce n'est pas dans la chaîne, il fait le numéro 47.
Maltysen
@Maltysen La question ne dit jamais quoi faire avec une entrée en dehors de la plage appropriée.
Scimonster
Vrai. Je voulais qu'il soit ignoré, mais comme je suppose que c'est ma faute de ne pas être suffisamment précis, je le permettrai.
Maltysen du
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}]]/@#]&

Prend la liste des fichiers d'entrée, du BPM et du nombre de demi-pas à transposer en entrée et joue le son (à partir d'un piano, tout autre instrument prendrait plus d'octets.) Ne sonne pas si mal!

LegionMammal978
la source
1

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

Tout d'abord, voici un extrait exécutable qui utilise des <input>champs au lieu de lectures de fichiers:

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

Et maintenant, l'entrée réelle:

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

Les trois arguments sont un tableau de chaînes de chemin de fichier à jouer simultanément, des notes par minute et un nombre de demi-étapes pour transposer toutes les entrées.

Avec des espaces et des commentaires:

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)
absides
la source