Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09539c9d authored by mike dooley's avatar mike dooley
Browse files

Adding GetModelState button to SoundTriggerTestApp

also using loadGenericSoundModel instead of addOrUpdateSoundModel

Change-Id: If4b6b6a467c839a74871d2f54a94af31fcf9c10c
parent e6a0a27c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -73,6 +73,14 @@
            android:text="@string/play_trigger"
            android:onClick="onPlayTriggerButtonClicked"
            android:padding="20dp" />

        <Button
            android:id="@+id/get_state_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/get_model_state"
            android:onClick="onGetModelStateButtonClicked"
            android:padding="20dp" />
    </LinearLayout>

    <LinearLayout
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
    <string name="start_recog">Start</string>
    <string name="stop_recog">Stop</string>
    <string name="play_trigger">Play Trigger Audio</string>
    <string name="get_model_state">Get State</string>
    <string name="capture">Capture Audio</string>
    <string name="stop_capture">Stop Capturing Audio</string>
    <string name="play_capture">Play Captured Audio</string>
+8 −0
Original line number Diff line number Diff line
@@ -257,6 +257,14 @@ public class SoundTriggerTestActivity extends Activity implements SoundTriggerTe
        }
    }

    public synchronized void onGetModelStateButtonClicked(View v) {
        if (mService == null) {
            Log.e(TAG, "Can't get model state: not bound to SoundTriggerTestService");
        } else {
            mService.getModelState(mSelectedModelUuid);
        }
    }

    public synchronized void onCaptureAudioCheckboxClicked(View v) {
        // See if we have the right permissions
        if (!mService.hasMicrophonePermission()) {
+63 −7
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
@@ -46,6 +48,7 @@ import java.util.Properties;
import java.util.Random;
import java.util.UUID;


public class SoundTriggerTestService extends Service {
    private static final String TAG = "SoundTriggerTestSrv";
    private static final String INTENT_ACTION = "com.android.intent.action.MANAGE_SOUND_TRIGGER";
@@ -57,6 +60,8 @@ public class SoundTriggerTestService extends Service {
    private Random mRandom;
    private UserActivity mUserActivity;

    private static int captureCount;

    public interface UserActivity {
        void addModel(UUID modelUuid, String state);
        void setModelState(UUID modelUuid, String state);
@@ -131,6 +136,8 @@ public class SoundTriggerTestService extends Service {
                        } else if (command.equals("set_capture_timeout")) {
                            setCaptureAudioTimeout(getModelUuidFromIntent(intent),
                                    intent.getIntExtra("timeout", 5000));
                        } else if (command.equals("get_model_state")) {
                            getModelState(getModelUuidFromIntent(intent));
                        } else {
                            Log.e(TAG, "Unknown command '" + command + "'");
                        }
@@ -432,6 +439,17 @@ public class SoundTriggerTestService extends Service {
        return modelInfo != null && modelInfo.captureAudioTrack != null;
    }

    public synchronized void getModelState(UUID modelUuid) {
        ModelInfo modelInfo = mModelInfoMap.get(modelUuid);
        if (modelInfo == null) {
            postError("Could not find model for: " + modelUuid.toString());
            return;
        }
        int status = mSoundTriggerUtil.getModelState(modelUuid);
        postMessage("GetModelState for: " + modelInfo.name + " returns: "
            + status);
    }

    private void loadModelsInDataDir() {
        // Load all the models in the data dir.
        boolean loadedModel = false;
@@ -527,18 +545,29 @@ public class SoundTriggerTestService extends Service {
        }
    }


    private class CaptureAudioRecorder implements Runnable {
        private final ModelInfo mModelInfo;

        // EventPayload and RecognitionEvent are equivalant.  Only one will be non-null.
        private final SoundTriggerDetector.EventPayload mEvent;
        private final RecognitionEvent mRecognitionEvent;

        public CaptureAudioRecorder(ModelInfo modelInfo, SoundTriggerDetector.EventPayload event) {
            mModelInfo = modelInfo;
            mEvent = event;
            mRecognitionEvent = null;
        }

        public CaptureAudioRecorder(ModelInfo modelInfo, RecognitionEvent event) {
            mModelInfo = modelInfo;
            mEvent = null;
            mRecognitionEvent = event;
        }

        @Override
        public void run() {
            AudioFormat format = mEvent.getCaptureAudioFormat();
            AudioFormat format = getAudioFormat();
            if (format == null) {
                postErrorToast("No audio format in recognition event.");
                return;
@@ -600,18 +629,21 @@ public class SoundTriggerTestService extends Service {
                }

                audioRecord = new AudioRecord(attributes, format, bytesRequired,
                        mEvent.getCaptureSession());
                        getCaptureSession());

                byte[] buffer = new byte[bytesRequired];

                // Create a file so we can save the output data there for analysis later.
                FileOutputStream fos  = null;
                try {
                    fos = new FileOutputStream( new File(
                    File file = new File(
                        getFilesDir() + File.separator
                        + mModelInfo.name.replace(' ', '_')
                        + "_capture_" + format.getChannelCount() + "ch_"
                                    + format.getSampleRate() + "hz_" + encoding + ".pcm"));
                        + format.getSampleRate() + "hz_" + encoding
                        + "_" + (++captureCount) + ".pcm");
                    Log.i(TAG, "Writing audio to: " + file);
                    fos = new FileOutputStream(file);
                } catch (IOException e) {
                    Log.e(TAG, "Failed to open output for saving PCM data", e);
                    postErrorToast("Failed to open output for saving PCM data: "
@@ -635,6 +667,10 @@ public class SoundTriggerTestService extends Service {
                    bytesRequired -= bytesRead;
                }
                audioRecord.stop();
                if (fos != null) {
                  fos.flush();
                  fos.close();
                }
            } catch (Exception e) {
                Log.e(TAG, "Error recording trigger audio", e);
                postErrorToast("Error recording trigger audio: " + e.getMessage());
@@ -651,6 +687,26 @@ public class SoundTriggerTestService extends Service {
                setModelState(mModelInfo, "Recording finished");
            }
        }

        private AudioFormat getAudioFormat() {
            if (mEvent != null) {
                return mEvent.getCaptureAudioFormat();
            }
            if (mRecognitionEvent != null) {
                return mRecognitionEvent.captureFormat;
            }
            return null;
        }

        private int getCaptureSession() {
            if (mEvent != null) {
                return mEvent.getCaptureSession();
            }
            if (mRecognitionEvent != null) {
                return mRecognitionEvent.captureSession;
            }
            return 0;
        }
    }

    // Implementation of SoundTriggerDetector.Callback.
+32 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.test.soundtrigger;

import android.annotation.Nullable;
import android.content.Context;
import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
import android.media.soundtrigger.SoundTriggerDetector;
import android.media.soundtrigger.SoundTriggerManager;
import android.os.RemoteException;
@@ -27,6 +29,7 @@ import android.util.Log;

import com.android.internal.app.ISoundTriggerService;

import java.lang.reflect.Method;
import java.lang.RuntimeException;
import java.util.UUID;

@@ -50,13 +53,31 @@ public class SoundTriggerUtil {
     * The sound model must contain a valid UUID.
     *
     * @param soundModel The sound model to add/update.
     * @return The true if the model was loaded successfully, false otherwise.
     */
    public boolean addOrUpdateSoundModel(SoundTriggerManager.Model soundModel) {
        if (soundModel == null) {
            throw new RuntimeException("Bad sound model");
        }
        mSoundTriggerManager.updateModel(soundModel);
        return true;
        // TODO: call loadSoundModel in the soundtrigger manager updateModel method
        // instead of here. It is needed to keep soundtrigger manager internal
        // state consistent.
        return mSoundTriggerManager
                .loadSoundModel(getGenericSoundModel(soundModel)) == 0;
    }

    private GenericSoundModel getGenericSoundModel(
        SoundTriggerManager.Model soundModel) {
        try {
            Method method = SoundTriggerManager.Model.class
                            .getDeclaredMethod("getGenericSoundModel");
            method.setAccessible(true);
            return (GenericSoundModel) method.invoke(soundModel);
        } catch (ReflectiveOperationException e) {
            Log.e(TAG, "Failed to getGenericSoundModel: " + soundModel, e);
            return null;
        }
    }

    /**
@@ -92,6 +113,16 @@ public class SoundTriggerUtil {
        return true;
    }

    /**
     * Get the current model state
     *
     * @param modelId The model ID to look-up the sound model for.
     * @return 0 if the call succeeds, or an error code if it fails.
     */
    public int getModelState(UUID modelId) {
        return mSoundTriggerManager.getModelState(modelId);
    }

    public SoundTriggerDetector createSoundTriggerDetector(UUID modelId,
            SoundTriggerDetector.Callback callback) {
        return mSoundTriggerManager.createSoundTriggerDetector(modelId, callback, null);