Prononcer à voix haute des chiffres de 0 à 9

15

Inspiré par cette question de l'électronique.SE , voici un défi pour vous:

Écrivez un programme ou un sous-programme qui prend une séquence de chiffres décimaux (0 à 9) et les prononce à haute voix, sans utiliser un outil de synthèse vocale existant.

Contribution:

Vous pouvez demander que les chiffres d'entrée soient fournis dans n'importe quel format raisonnable, par exemple sous la forme d'une chaîne de chiffres ASCII, d'un tableau d'entiers, d'un numéro codé BCD, etc. Si votre solution est un programme exécutable, vous pouvez prendre l'entrée comme un paramètre de ligne de commande, lisez-le à partir de l'entrée standard ou obtenez-le de toute autre manière raisonnable.

Votre programme doit être capable de parler au moins huit chiffres par appel. Vous pouvez supposer que le premier chiffre n'est pas zéro, sauf s'il s'agit du seul chiffre.

Production:

Votre programme peut soit prononcer les chiffres directement à l'aide d'un périphérique audio, soit produire un fichier audio lisible. Le fichier de sortie, le cas échéant, peut être dans n'importe quel format audio standard, ou il peut être constitué de données d'échantillon brutes. Si vous sortez des données d'échantillon brutes, veuillez noter les paramètres appropriés pour la lecture (fréquence d'échantillonnage, bits par échantillon, endianness, signé / non signé, # de canaux). Les formats pris en charge par aplay sont préférés.

Vous êtes libre de décider des détails sur la façon dont les chiffres seront prononcés, mais votre sortie doit être composée de chiffres de langue anglaise parlés d'une manière compréhensible pour un anglophone typique , et il doit être suffisamment clair pour que l'auditeur puisse transcrire avec précision un nombre aléatoire prononcé à huit chiffres. Non, juste bips n ne compte pas. N'oubliez pas d'inclure des pauses entre les chiffres.

Notation:

Les règles standard de notation par s'appliquent: votre score est la longueur de votre code en octets ou, si votre code est écrit en texte Unicode, en caractères Unicode. Le score le plus bas l'emporte. N'importe quelle langue va.

Comme la question d'origine sur l'électronique.SE concernait la programmation intégrée, j'ai pensé qu'il serait approprié de jeter un os aux auteurs utilisant des langages de bas niveau: si votre solution est écrite dans un langage compilé, vous pouvez choisir de compter la longueur du fichier exécutable compilé en octets comme score. (Oui, le bytecode précompilé, tel qu'un .classfichier Java , est OK aussi.) Si vous choisissez d'utiliser cette option, veuillez inclure une copie de l'exécutable compilé dans votre réponse (par exemple, comme un vidage hexadécimal) avec votre code source et la version du compilateur et les options que vous avez utilisées pour le générer.

Une mention honorable , avec une prime de +50 rep, sera accordée à la première réponse qui répond également aux critères de la question d'origine , c'est-à-dire capable de fonctionner sur un MCU intégré avec 4 ko de flash et 1 ko de SRAM.

Restrictions:

Vous ne pouvez pas utiliser de fichiers ou de ressources réseau qui ne font pas partie de l'environnement d'exécution standard de votre langue choisie, sauf si vous comptez la longueur desdits fichiers ou ressources dans votre score. (C'est pour interdire par exemple le chargement d'échantillons audio à partir du Web.)

Vous ne pouvez pas non plus utiliser d' outils ou de bibliothèques de synthèse vocale préexistants ou des compilations de données audio (sauf si vous comptez également leur taille dans le cadre de votre partition), même s'ils sont inclus dans l'environnement d'exécution standard de la langue de votre choix.

Ilmari Karonen
la source
Ps. Je pourrai publier ma propre solution plus tard, si je parviens à la faire produire quelque chose qui semble réellement compréhensible. Mais n'hésitez pas à publier le vôtre; à ce stade, toute réponse est une bonne réponse.
Ilmari Karonen
1
Sommes-nous autorisés à télécharger une base de données de chiffres parlés (et à compter sa taille dans la partition) ou devons-nous enregistrer notre propre voix? Je doute que je puisse générer des échantillons de parole de manière algorithmique.
John Dvorak
umm ... la section "sortie" ne précise pas que nous devons sortir des échantillons de parole. Sommes-nous autorisés à émettre simplement un bip dix fois?
John Dvorak
@PeterTaylor: Si vous comptez leur taille dans votre score, c'est OK. J'étais juste inquiet qu'il puisse y avoir un système qui a des échantillons audio de chiffres enterrés quelque part dans son environnement d'exécution standard.
Ilmari Karonen
3
Puisqu'il semble y avoir un flux constant de personnes qui ne lisent pas la question à la fin et ne publient pas de wrappers triviaux autour de bibliothèques lourdes, il pourrait être utile de modifier pour mettre encore plus l'accent sur l'aspect "Do it yourself".
Peter Taylor

Réponses:

10

ruby - 3710 = code à 90 caractères + 3620 octets de données

require'zlib'
$><<$*[0].chars.map{|x|Zlib::Inflate.inflate File.open(x).read}.join(?0*5e3)

entrée: un seul argument de ligne de commande, le nombre à lire

sortie: données sonores brutes, PCM 8 bits / 8 kHz

Cela peut lire n'importe quelle chaîne d'entrée, tant que

  • il ne contient que des caractères qui sont des noms de fichiers valides. pour seulement quatre caractères, vous pouvez agrandir cet ensemble à tous les caractères.
  • vous avez les fichiers nécessaires.
  • pourquoi oh vous espace dee oh en apostrophe tee espace em i en dee space tee aitch i es période

5e3code la pause entre deux mots. Ici, 5 échantillons ~ = 0,6 s. Ajustez comme vous le souhaitez.

Maintenant, la partie délicate est d'obtenir les fichiers d'exemple en 4K et de pouvoir les décompresser facilement et en qualité suffisante. Voici comment je les ai obtenus:

  • Prenez un moteur de synthèse vocale capable de produire des fichiers audio. Wikipédia en a un .
  • Donnez-lui un texte contenant tous les chiffres, idéalement rapprochés. J'ai utilisé http://en.wikipedia.org/wiki/Base_13
  • Sous-échantillonnage.
  • Découpez chaque partie dans un éditeur de sons .
  • Enregistrer en tant que fichier brut.
  • Décimez chaque échantillon (jetez les bits de poids faible).
  • Dégonfler.

Maintenant, il faut choisir un taux d'échantillonnage et une quantité de décimation. Trop et le son ne sera pas compréhensible. Trop peu et vous ne rentrez pas. Je me suis contenté de 8kHz / 3b. Les voici : https://github.com/honnza/drops/raw/master/digits.zip

  • 8KHz * 4b / échantillon et qualité supérieure - trop grand
  • 8KHz * 3b / échantillon - basse qualité, mais il s'intègre dans 4K
  • 8KHz * 2b / échantillon - kch kchhhhhhhhh [incompréhensible]
  • 2KHz * 8b / échantillon - trop grand
  • 2KHz * 3b / échantillon - kch kchhhhhhhhhh
  • 1 KHz * 8b / échantillon - kch kchhhhhhhhhh

Voici le script de décimation:

require'zlib'
Dir.glob "*.raw" do |fname|
  File.open fname[/\d/], "wb" do |out|
    File.open fname do |input|
      bytes = input.bytes.to_a
      bytes.map! {|x|x&0xE0}
      dfl = Zlib::Deflate.deflate(bytes.pack("C*"),9)
      dfl.each_byte do |byte|
        out.print byte.chr
      end
      puts "done #{fname}: #{dfl.size}"
    end
  end
end

Quant au défi d'origine: il y a 476 octets d'espace pour le code et la table de fichiers. Cela peut être un peu trop selon la taille que nous pouvons obtenir avec une bibliothèque DEFLATE. Si nécessaire, nous pouvons couper quelques coins ici et là en recadrant les échantillons audio de manière un peu plus agressive. [fo:r]ou[o:] n'a pas vraiment d'importance, mais il économise des octets. J'ai été quelque peu bienveillant en recadrant les chiffres. En outre, un schéma de décimation différent ou sacrifier une décimation pour le sous-échantillonnage pourrait aider - je jouerai avec ceux-ci plus tard. De plus, la suppression des en-têtes DEFLATE peut économiser une petite quantité d'espace.

La concaténation d'échantillons sonores est assez facile, mais 4K est un peu à l'étroit. Si vous n'êtes pas lié par l'espace 4k, je suggère moins de décimation. 4 bits par échantillon se portent plutôt bien et ne sont que légèrement plus gros.

John Dvorak
la source
+1, pas mal. La clarté est cependant assez marginale: j'ai essayé de transcrire quelques nombres aléatoires et j'ai obtenu un taux de réussite d'environ 70%. (J'espérais quelque chose de plus proche de 99%.) Je suis également encore un peu sur la clôture au sujet de la mention honorable: bien que vous ayez avancé un assez bon argument selon lequel 4K pourrait être atteint de cette façon, vous ne l'avez pas en fait démontré. Même si vous avez abandonné Ruby pour C (ce qui semble assez facile à faire; je serais prêt à jouer ce rôle avec foi), pourriez-vous vraiment installer un décodeur DEFLATE dans l'espace flash restant? De plus, comme je l'ai noté, la qualité sonore est assez mauvaise.
Ilmari Karonen
Ps. Quelques conseils pour une meilleure compression: vous pouvez remplir tous les échantillons à une longueur fixe avec des octets nuls (qui devraient bien compresser) et les concaténer en un seul fichier compressé, puis le décompresser et le découper. De plus, l'astuce KZIP de cette réponse pourrait vous donner une meilleure compression DEFLATE. Enfin, essayez de modifier le fichier audio combiné pour remplacer les phonèmes équivalents par des copies exactes.
Ilmari Karonen
eh bien, les échantillons sonores originaux n'étaient pas exactement compréhensibles non plus OMI - le sous-échantillonnage n'a fait que peu de dégâts. La plus petite bibliothèque DEFLATE que je connaisse - la première liée par wikipeda - pèse environ 500 milliards. Franchement, voulez-vous que je transfère le gonfleur sur cet appareil spécifique? Je pourrais y arriver en fait, mais je n'ai jamais codé pour ARM auparavant.
John Dvorak
Je suis assez surpris du taux de réussite de 70% - j'ai trouvé les chiffres faciles à comprendre. Quels chiffres avez-vous le plus confondus?
John Dvorak
Le porter sur un Cortex M0 est probablement un peu trop demander (bien que si vous pouviez le faire, ce serait génial!), Mais je pense qu'un binaire autonome (+ fichiers de données, le cas échéant) convenant à 4k semblerait une démonstration raisonnable. (Pas besoin de lier statiquement dans libc pour les E / S de fichiers, car vous n'en auriez pas besoin sur un périphérique intégré, mais le code DEFLATE devrait certainement être compté.) Fondamentalement, quelque chose que vous pourriez publier comme réponse à la question d'origine sur electronics.SE et dire en toute confiance "si vous compilez cela pour votre appareil, je parie que ça ira".
Ilmari Karonen