venerdì 27 gennaio 2017

AudioRecord su Android

Per registrare i dati raw dal microfono di Android e' necessario utilizzare AudioRecord (non MediaRecord)

quello che viene riportato in calce e' il codice per utilizzare questa libreria (e' un copia/incolla da piu' fonti...di mio non c'e' praticamente niente se non il fatto di avere messo insieme i pezzi per farlo funzionare da Android 6 in poi)

Un paio di trucchi: non e' sufficiente aggiungere i permessi di accedere al microfono (RECORD AUDIO) dentro al file  Manifest ma devono essere anche esplicitamente i permessi a livello di codice (la funzione requestRecordAudioPermission)

i dati vengono inseriti in un buffer per poi essere post processati e sono in formato di short signed (32768/-32767)


------------------------------

public class MainActivity extends AppCompatActivity {

    private Button play;
    final int SAMPLE_RATE = 8000;
    boolean mShouldContinue;
    String LOG_TAG = "Audio";
    private Button stop;


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

        requestRecordAudioPermission();

        play = (Button) findViewById(R.id.button);
        stop = (Button) findViewById(R.id.button2);

      
        play.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                mShouldContinue = true;
                recordAudio();
            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override            public void onClick(View view) {
                mShouldContinue = false;
            }
        });

    }


    private void requestRecordAudioPermission() {
        //check API version, do nothing if API version < 23!        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (currentapiVersion > android.os.Build.VERSION_CODES.LOLLIPOP){

            if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {

                // Should we show an explanation?                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {

                    // Show an expanation to the user *asynchronously* -- don't block                    // this thread waiting for the user's response! After the user                    // sees the explanation, try again to request the permission.
                } else {

                    // No explanation needed, we can request the permission.
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
                }
            }
        }
    }

    @Override    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {
                // If request is cancelled, the result arrays are empty.                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the                    // contacts-related task you need to do.                    Log.d("Activity", "Granted!");

                } else {

                    // permission denied, boo! Disable the                    // functionality that depends on this permission.                    Log.d("Activity", "Denied!");
                    finish();
                }
                return;
            }

            // other 'case' lines to check for other            // permissions this app might request        }
    }

    synchronized void recordAudio() {
        new Thread(new Runnable() {
            @Override            public void run() {
                Log.d(LOG_TAG, "Start ");

                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);

                // buffer size in bytes                int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                        AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT);
                Log.d(LOG_TAG, "Buffer Size " + Integer.toString(bufferSize));

                if (bufferSize == AudioRecord.ERROR || bufferSize == AudioRecord.ERROR_BAD_VALUE) {
                    bufferSize = SAMPLE_RATE * 2;
                }

                short[] audioBuffer = new short[bufferSize / 2];

                AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                        SAMPLE_RATE,
                        AudioFormat.CHANNEL_IN_MONO,
                        AudioFormat.ENCODING_PCM_16BIT,
                        bufferSize);

                if (record.getState() != AudioRecord.STATE_INITIALIZED) {
                    Log.e(LOG_TAG, "Audio Record can't initialize!");
                    return;
                }
                record.startRecording();

                Log.v(LOG_TAG, "Start recording");

                long shortsRead = 0;
                while (mShouldContinue) {
                    int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length);
                    shortsRead += numberOfShort;



                    for(int i = 0; i < numberOfShort; i++){
                        Log.d(LOG_TAG,String.valueOf(audioBuffer[i]));                    }

                }

                record.stop();
                record.release();

                Log.v(LOG_TAG, String.format("Recording stopped. Samples read: %d", shortsRead));

            }
        }).start();
    }
}

Nessun commento:

Posta un commento

Physics informed neural network Fukuzono

Visto che puro ML non funziona per le serie tempo di cui mi sto occupando ed le regressioni basate su formule analitiche mostrano dei limiti...