JavascriptProva

martedì 15 novembre 2016

Audiotrack: per far emettere toni puri al cellulare.

Ora proviamo a costruire un dispositivo che emetta una frequenza sonora.
Dobbiamo costruire la classe AndroidAudioDevice.
Ci provo.

Dichiariamo intanto le due variabili, l'una che mi sembra la più importante, di tipo AudioTrack, e l'altra che è una matrice di short, il buffer.
    class AndroidAudioDevice{
        AudioTrack track;
        short[] buffer = new short[1024];
    }
Bene. E ora?
Ora c'è il costruttore, in cui: si ottiene un int minSize, che dovrebbe essere la minima dimensione del buffer.
Vediamolo
    class AndroidAudioDevice{
        AudioTrack track;
        short[] buffer = new short[1024];

        int minSize=AudioTrack.getMinBufferSize(44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
    }
Quindi si definisce track:
        public AndroidAudioDevice() {
            int minSize = AudioTrack.getMinBufferSize(44100,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

            track = new AudioTrack(AudioManager.STREAM_MUSIC,
                    44100,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT,
                    minSize,
                    AudioTrack.MODE_STREAM);
           track.play();
        }
Aggiungo track.play() ed ecco tutto il costruttore.
Ora bisognerebbe creare il metodo writeSamples che ha per parametri un array di float.
Provo...
        public void writeSamples(float[] samples){
            fillBuffer(samples);
        }
Questo passa subito al metodo privato fillBuffer (che ancora non esiste) il suo parametro array di float.
Quindi scrive su track quello che legge sul buffer che è "di ritorno" da fillBuffer.
        public void writeSamples(float[] samples){
            fillBuffer(samples);
            track.write(buffer,0,samples.length);
        }
E ora resta da definire fillBuffer.

        private void fillBuffer(float[] samples){
            
        }
nel quale prima si adeguano le dimensioni del buffer all'array di samples.
        private void fillBuffer(float[] samples){
            if(buffer.length < samples.length){
                buffer=new short[samples.length];
            }
        }
e quindi si prendono uno per uno tutti i float di samples e si convertono in short per trasferirli nell'array di short che è buffer.
                for(int i=0;i<samples.length;i++){
                    buffer[i]=(short)(samples[i]*Short.MAX_VALUE);
                }
Ecco.
Mi riscrivo qui il codice completo:
public class MainActivity extends AppCompatActivity {


    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    class AndroidAudioDevice{
        AudioTrack track;
        short[] buffer = new short[1024];

        public AndroidAudioDevice() {
            int minSize = AudioTrack.getMinBufferSize(44100,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

            track = new AudioTrack(AudioManager.STREAM_MUSIC,
                    44100,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT,
                    minSize,
                    AudioTrack.MODE_STREAM);
            track.play();
        }

        public void writeSamples(float[] samples){
            fillBuffer(samples);
            track.write(buffer,0,samples.length);
        }

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

Nessun commento:

Posta un commento