JavascriptProva

lunedì 14 novembre 2016

AudioTrack, per far emettere toni allo smartphone. Scontro con i numeri in virgola mobile.

Questo è il link per la riproduzione di toni.

Bisogna costruire una classe AndroidAudioDevice.
Poi si definiscono delle variabili che sono una di tipo AudioTrack e una di tipo matrice di short (short[]).
Quindi il costruttore.
Nel costruttore si definisce minSize (che dovrebbe essere la dimensione minima del buffer).
minsize viene definito usando il metodo AudioTrack.getBufferSize.
Questo deve restituire un int.
Usa come parametri 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT.

44100 è la frequenza di campionamento.
Il secondo parametro è MONO o STEREO.
Il terzo è il formato dei dati, 8 bit o 16 bit o altro (che al momento non mi viene in mente).

Segue il costruttore dell'oggetto di classe AudioTrack specificato fra le variabili iniziali, che usa come parametri il già visto minSize più i parametri che il metodo getMinSize utilizzava, più altri due parametri.
Quindi nel costruttore si dà un valore alla variabile track di classe AudioTrack, e quindi si invoca il metodo play() di questa AudioTrack.

La classe che sto creando, ossia AndroidAudioDevice, oltre al costruttore ha anche il metodo writeSamples().
   public void writeSamples(float[] samples) 
   { 
      fillBuffer( samples );
      track.write( buffer, 0, samples.length );
   }
Questo metodo ha come parametro una matrice di tipo float[] e la usa come parametro del metodo privato fillBuffer().
Vediamolo:
   private void fillBuffer( float[] samples )
   {
      if( buffer.length < samples.length )
         buffer = new short[samples.length];
 
      for( int i = 0; i < samples.length; i++ )
         buffer[i] = (short)(samples[i] * Short.MAX_VALUE);
   } 
Accoglie come parametro la matrice float[] che gli viene passata da writeSamples che lo invoca.
Con le prime due righe...
      if( buffer.length < samples.length )
         buffer = new short[samples.length];
...se la grandezza del buffer è di dimensioni inferiori a quella del parametro che viene passato, crea una nuova matrice come buffer, di dimensioni uguali a quelle del parametro;
quindi per ogni elemento contenuto nella matrice samples si prende un elemento del buffer e gli si dà il valore, castato a short, del corrispondente elemento di samples moltiplicato per Short.MAX_VALUE.
Cosa significa questo Short.MAX_VALUE?


Viene moltiplicato un tipo float per Short.MAX_VALUE.
Vediamo se riesco a trovare qualche ispirazione cercando intorno alla conversione short -> float.

Per capire tutto questo forse devo ripassarmi bene come sono strutturati i numeri in virgola mobile.

Quando io moltiplico un float per uno short, lo short viene preventivamente convertito in float?
Se do a uno short un valore superiore al suo massimo, che valore assume la variabile?

Vediamo...

Mi devo costruire dei modelli.

Ecco, come ricordavo, la moltiplicazione di un float per uno short dà un risultato di tipo float.
        float numeroFloat = 5.2f;

        short numeroShort=2;

        float risultato=numeroFloat * numeroShort;

        System.out.println(risultato);
Ottengo come risultato:
11-14 17:06:10.752 4130-4130/? I/System.out: 10.4

Se invece do al risultato il tipo short:
        float numeroFloat = 5.2f;

        short numeroShort=2;

        short risultato=numeroFloat * numeroShort;

        System.out.println(risultato);
...ottengo un errore, perché il risultato non può essere short ma è float.
Ora è il caso di ripassare a dovere i numeri in virgola mobile, perché credo che una risposta mi può venire solo da lì.

Nessun commento:

Posta un commento