Pronunciare le cifre da 0 a 9 ad alta voce


15

Ispirato da questa domanda di electronics.SE , ecco una sfida per te:

Scrivi un programma o una subroutine che accetta una sequenza di cifre decimali (da 0 a 9) e le pronuncia ad alta voce, senza utilizzare uno strumento di sintesi vocale esistente.

Ingresso:

È possibile richiedere che le cifre di input vengano fornite in qualsiasi formato ragionevole, ad esempio come una stringa di cifre ASCII, una matrice di numeri interi, un numero codificato BCD, ecc. Se la soluzione è un programma eseguibile, è possibile prendere l'input come un parametro della riga di comando, leggerlo dall'input standard o ottenerlo in qualsiasi altro modo ragionevole.

Il tuo programma deve essere in grado di pronunciare almeno otto cifre per chiamata. Si può presumere che la prima cifra non sia zero, a meno che non sia l'unica cifra.

Produzione:

Il tuo programma può pronunciare i numeri direttamente utilizzando un dispositivo audio o può generare un file audio riproducibile. Il file di output, se presente, può essere in qualsiasi formato audio standard o può essere costituito da dati di esempio non elaborati. Se si producono dati di campionamento non elaborati, tenere presente i parametri appropriati per la riproduzione (frequenza di campionamento, bit per campione, endianness, con / senza segno, numero di canali). Sono preferiti i formati supportati da aplay .

Sei libero di decidere i dettagli su come i numeri saranno pronunciati, ma il tuo output dovrebbe consistere in cifre in lingua inglese parlate in modo comprensibile a un tipico oratore inglese e dovrebbe essere abbastanza chiaro per l'ascoltatore da poter trascrivere accuratamente un numero casuale di otto cifre parlato. No, solo il segnale acustico n volte non conta. Non dimenticare di includere pause tra le cifre.

punteggio:

Si applicano le regole standard per il : il tuo punteggio è la lunghezza del tuo codice in byte o, se il tuo codice è scritto nel testo Unicode, in caratteri Unicode. Il punteggio più basso vince. Qualsiasi lingua va.

Poiché la domanda originale sull'elettronica.SE riguardava la programmazione integrata, ho ritenuto opportuno gettare un osso agli autori che usano linguaggi di basso livello: se la tua soluzione è scritta in un linguaggio compilato, puoi scegliere di contare la lunghezza del file eseguibile compilato in byte come punteggio. (Sì, anche il codice precompilato, come un .classfile Java , va bene.) Se si sceglie di utilizzare questa opzione, si prega di includere una copia dell'eseguibile compilato nella risposta (ad es. Come un dump esadecimale) insieme al codice sorgente e la versione del compilatore e le opzioni utilizzate per generarlo.

Una menzione d'onore , insieme a una ricompensa di +50, verrà data alla prima risposta che soddisfa anche i criteri della domanda originale , ovvero è in grado di funzionare su un MCU incorporato con 4 kb di flash e 1 kb di SRAM.

restrizioni:

Non è possibile utilizzare file o risorse di rete che non fanno parte dell'ambiente di runtime standard della lingua prescelta, a meno che non si contenga la lunghezza di tali file o risorse come parte del punteggio. (Questo non consente ad esempio il caricamento di campioni audio dal Web.)

Non è inoltre possibile utilizzare strumenti di sintesi vocale o librerie o raccolte di dati audio preesistenti (a meno che non si contino anche le loro dimensioni come parte della partitura), anche se sono inclusi nell'ambiente di runtime standard della lingua prescelta.


Ps. Potrei pubblicare una mia soluzione in seguito, se riesco a farla produrre qualcosa che suona davvero comprensibile. Non essere timido nel pubblicare il tuo, però; a questo punto, qualsiasi risposta è una buona risposta.
Ilmari Karonen,

1
Siamo autorizzati a scaricare un database di cifre parlate (e contare le sue dimensioni per il punteggio) o dobbiamo registrare la nostra voce? Dubito di poter generare campioni vocali in modo algoritmico.
John Dvorak,

umm ... la sezione "output" non specifica che dobbiamo produrre campioni vocali. Ci è permesso semplicemente emettere un segnale acustico dieci volte?
John Dvorak,

@PeterTaylor: se conti le loro dimensioni come parte del tuo punteggio, va bene. Ero solo preoccupato che potesse esserci qualche sistema là fuori che ha campioni audio di cifre sepolti da qualche parte nel suo ambiente di runtime standard.
Ilmari Karonen,

3
Dal momento che sembra esserci un flusso costante di persone che non leggono la domanda fino in fondo e pubblicano banali involucri attorno a biblioteche di pesi massimi, potrebbe valere la pena di apportare modifiche per porre ancora più enfasi sull'aspetto "Fai da te".
Peter Taylor,

Risposte:


10

ruby - 3710 = codice di 90 caratteri + 3620 byte di dati

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

input: un singolo argomento della riga di comando, il numero da leggere

uscita: dati audio grezzi, PCM 8 bit / 8 kHz

Questo può leggere qualsiasi stringa di input, purché

  • contiene solo caratteri che sono nomi di file validi. per soli quattro caratteri, puoi ingrandire quello impostato su tutti i personaggi.
  • hai i file necessari.
  • perché oh, spazio, spazio, apostrofo, spazio, spazio, tempo, periodo

5e3codifica la pausa tra due parole. Qui, 5 campioni ~ = 0,6 s. Modifica come desiderato.

Ora, la parte difficile è ottenere i file di esempio in 4K e riuscire a decomprimerli facilmente e con una qualità sufficiente. Ecco come li ho ottenuti:

  • Prendi un motore di sintesi vocale in grado di produrre file audio. Wikipedia ne ha uno .
  • Inseriscilo un testo contenente tutte le cifre, idealmente vicine tra loro. Ho usato http://en.wikipedia.org/wiki/Base_13
  • Downsample.
  • Taglia ogni parte in un editor sonoro .
  • Salva come file non elaborato.
  • Decimare ciascun campione (scartare i bit di ordine inferiore).
  • Sgonfiare.

Ora, si deve scegliere una frequenza di campionamento e un importo di decimazione. Troppo, e il suono non sarà comprensibile. Troppo poco e non ti adatti. Ho optato per 8kHz / 3b. Eccoli : https://github.com/honnza/drops/raw/master/digits.zip

  • 8KHz * 4b / campione e qualità superiore - troppo grande
  • 8KHz * 3b / campione - bassa qualità, ma si adatta al 4K
  • 8KHz * 2b / campione - kch kchhhhhhhhh [non comprensibile]
  • 2 KHz * 8b / campione - troppo grande
  • 2KHz * 3b / campione - kch kchhhhhhhhh
  • 1KHz * 8b / campione - kch kchhhhhhhhh

Ecco lo script di decimazione:

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

Per quanto riguarda la sfida originale: ci sono 476 byte di spazio per il codice e la tabella dei file. Questo potrebbe essere leggermente troppo a seconda di quanto possiamo ottenere con una libreria DEFLATE. Se necessario, possiamo tagliare alcuni angoli qua e là ritagliando un po 'più aggressivamente i campioni audio. [fo:r]o [o:]non importa davvero ma salva byte. Sono stato un po 'benevolo nel ritagliare i numeri. Inoltre, un diverso schema di decimazione o sacrificare qualche decimazione per il downsampling potrebbe essere d'aiuto: giocherò con questi in seguito. Inoltre, rilasciare le intestazioni DEFLATE potrebbe risparmiare una piccola quantità di spazio.

Concatenare i campioni sonori è abbastanza semplice, ma il 4K è un po 'angusto. Se non sei vincolato dallo spazio 4k, suggerisco meno decimazione. 4 bit per campione in realtà vanno abbastanza bene ed è solo leggermente più grande.


+1, non male. La chiarezza è piuttosto marginale, però: ho provato a trascrivere alcuni numeri casuali e ho ottenuto un tasso di successo di circa il 70%. (Speravo in qualcosa di più vicino al 99%.) Sono anche ancora un po 'sulla recinzione dell'onorevole menzione: mentre hai argomentato abbastanza bene che il 4K potrebbe essere raggiungibile in questo modo, non hai effettivamente dimostrato. Anche se hai abbandonato il rubino per C (che sembra abbastanza facile da fare; sarei disposto a prendere quella parte sulla fede), potresti davvero inserire un decodificatore DEFLATE nello spazio flash rimanente? Inoltre, come ho notato, la qualità del suono è piuttosto scarsa.
Ilmari Karonen,

Ps. Alcuni consigli per una migliore compressione: potresti riempire tutti i campioni di una lunghezza fissa con byte nulli (che dovrebbero comprimersi bene) e concatenarli in un file compresso, quindi decomprimerlo e suddividerlo. Inoltre, il trucco KZIP da questa risposta potrebbe darti una migliore compressione DEFLATE. Infine, prova a modificare il file audio combinato per sostituire i fonemi equivalenti con copie esatte.
Ilmari Karonen,

beh, i campioni audio originali non erano esattamente comprensibili neanche dall'IMO - il downsampling ha fatto ben poco danno. La più piccola biblioteca DEFLATE che conosco - la prima collegata da Wikipeda - pesa circa 500 b. Francamente, vuoi che porti il ​​gonfiatore su quel dispositivo specifico? Potrei arrivare a questo in realtà, ma non ho mai codificato per ARM prima.
John Dvorak

Sono piuttosto sorpreso dal tasso di successo del 70%: ho trovato i numeri facili da capire. Quali cifre hai confuso di più?
John Dvorak

Il porting su un Cortex M0 è probabilmente un po ' troppo da chiedere (anche se se potessi farlo, sarebbe fantastico!), Ma penso che un binario autonomo (+ file di dati, se presente) si adatta sotto 4k sembrerebbe una dimostrazione ragionevole. (Non è necessario collegarsi staticamente in libc per l'I / O dei file, dal momento che non ne avresti bisogno su un dispositivo incorporato, ma il codice DEFLATE dovrebbe sicuramente essere conteggiato.) Fondamentalmente, qualcosa che potresti pubblicare come risposta alla domanda originale su electronics.SE e dì con sicurezza "se lo compili per il tuo dispositivo, scommetto che si adatterà".
Ilmari Karonen,
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.