This repository has been archived by the owner on May 24, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added voice trigger ("show me a demo"); updated code style to match t…
…hat of other samples.
- Loading branch information
Showing
11 changed files
with
394 additions
and
346 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,22 @@ | ||
apk-waveform-sample | ||
===================== | ||
Waveform | ||
======== | ||
|
||
A simple Glassware apk that receives audio input from the microphone and | ||
displays it on the screen as an animated waveform, along with the decibel | ||
This sample launches an immersion that receives audio input from the microphone | ||
and displays it on the screen as an animated waveform, along with the decibel | ||
level. | ||
|
||
## Prerequistes | ||
## Getting started | ||
|
||
* [Android SDK](http://developer.android.com/sdk/index.html) - This is needed for development. | ||
* [Glass](http://www.google.com/glass/start/how-to-get-one/) - You can push the code to an Android device but the goal of this project is to get started writing .apk for Glass. | ||
Check out our documentation to learn how to get started on | ||
https://developers.google.com/glass/develop/index | ||
|
||
## Importing and compiling the code | ||
## Running the sample on Glass | ||
|
||
Checkout the code into your filesystem and use your favorite IDE to import and compile the code. | ||
You can use your IDE to compile and install the sample or use | ||
[`adb`](https://developer.android.com/tools/help/adb.html) | ||
on the command line: | ||
|
||
### In Eclipse and ADT | ||
$ adb install -r WaveformSample.apk | ||
|
||
1. Click **File > Import ... > Existing Android Code into Workspace**. | ||
2. Click **Browse**, select the location of the `apk-waveform-sample/` directory, and click **OK**. | ||
3. Select the **apk-waveform-sample** project to import it and select | ||
**Copy projects into workspace**. | ||
6. Click **Finish** to complete the import. | ||
|
||
### In Android Studio | ||
|
||
1. Checkout the sample to a location where you keep your Android | ||
development projects. A `apk-waveform-sample/` directory is created. | ||
2. Click **File > Import Project...**, select the location of the `apk-waveform-sample/` directory, and click **Next** until you see the **Finish** button. | ||
3. Click **Finish** to complete the import. | ||
|
||
|
||
## Turning on debug mode | ||
|
||
You'll need to turn on debug mode before you do any type of development on | ||
Glass. Go to **Settings > Device Info > Turn on debug** to enable it. | ||
|
||
## Push the .apk on Glass | ||
|
||
You can use your IDE to compile, push and run the .apk or use this command line with `adb`: | ||
|
||
adb install -r apk-waveform-sample.apk | ||
|
||
## Run the .apk | ||
|
||
You can use your IDE to run the .apk or use this command line with `adb` when the Glass screen is **on**: | ||
|
||
adb shell am start -n com.google.glass.samples.waveform/.WaveformActivity | ||
To start the sample, say "ok glass, show me a demo" from the Glass clock | ||
screen or use the touch menu. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,36 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- Copyright (C) 2013 Google Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:keepScreenOn="true" | ||
android:background="@color/black" | ||
tools:context=".WaveformActivity" > | ||
android:layout_height="match_parent" > | ||
|
||
<com.google.glass.samples.waveform.WaveformView | ||
android:id="@+id/waveformView" | ||
<com.google.android.glass.sample.waveform.WaveformView | ||
android:id="@+id/waveform_view" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" /> | ||
|
||
<TextView | ||
android:id="@+id/decibelView" | ||
android:id="@+id/decibel_view" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:layout_gravity="bottom|right" | ||
android:layout_marginRight="@dimen/footer_right_margin" | ||
android:layout_marginBottom="@dimen/footer_bottom_margin" | ||
android:textSize="@dimen/footer_text_size" /> | ||
android:textAppearance="?android:attr/textAppearanceSmall" /> | ||
|
||
</FrameLayout> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,22 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- Copyright (C) 2013 Google Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<resources> | ||
|
||
<dimen name="footer_right_margin">40px</dimen> | ||
<dimen name="footer_bottom_margin">29px</dimen> | ||
<dimen name="footer_text_size">30px</dimen> | ||
|
||
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,24 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- Copyright (C) 2013 Google Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<resources> | ||
|
||
<string name="app_name">Waveform</string> | ||
<string name="show_me_a_demo">show me a demo</string> | ||
|
||
<string name="decibel_format">%1$.1f dB</string> | ||
|
||
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- Copyright (C) 2013 Google Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<trigger keyword="@string/show_me_a_demo" /> |
145 changes: 145 additions & 0 deletions
145
src/com/google/android/glass/sample/waveform/WaveformActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* Copyright (C) 2013 Google Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
* use this file except in compliance with the License. You may obtain a copy of | ||
* the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
* License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
|
||
package com.google.android.glass.sample.waveform; | ||
|
||
import android.app.Activity; | ||
import android.media.AudioFormat; | ||
import android.media.AudioRecord; | ||
import android.media.MediaRecorder.AudioSource; | ||
import android.os.Bundle; | ||
import android.widget.TextView; | ||
|
||
/** | ||
* Receives audio input from the microphone and displays a visualization of that data as a waveform | ||
* on the screen. | ||
*/ | ||
public class WaveformActivity extends Activity { | ||
|
||
// The sampling rate for the audio recorder. | ||
private static final int SAMPLING_RATE = 44100; | ||
|
||
private WaveformView mWaveformView; | ||
private TextView mDecibelView; | ||
|
||
private RecordingThread mRecordingThread; | ||
private int mBufferSize; | ||
private short[] mAudioBuffer; | ||
private String mDecibelFormat; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.layout_waveform); | ||
|
||
mWaveformView = (WaveformView) findViewById(R.id.waveform_view); | ||
mDecibelView = (TextView) findViewById(R.id.decibel_view); | ||
|
||
// Compute the minimum required audio buffer size and allocate the buffer. | ||
mBufferSize = AudioRecord.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, | ||
AudioFormat.ENCODING_PCM_16BIT); | ||
mAudioBuffer = new short[mBufferSize / 2]; | ||
|
||
mDecibelFormat = getResources().getString(R.string.decibel_format); | ||
} | ||
|
||
@Override | ||
protected void onResume() { | ||
super.onResume(); | ||
|
||
mRecordingThread = new RecordingThread(); | ||
mRecordingThread.start(); | ||
} | ||
|
||
@Override | ||
protected void onPause() { | ||
super.onPause(); | ||
|
||
if (mRecordingThread != null) { | ||
mRecordingThread.stopRunning(); | ||
mRecordingThread = null; | ||
} | ||
} | ||
|
||
/** | ||
* A background thread that receives audio from the microphone and sends it to the waveform | ||
* visualizing view. | ||
*/ | ||
private class RecordingThread extends Thread { | ||
|
||
private boolean mShouldContinue = true; | ||
|
||
@Override | ||
public void run() { | ||
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); | ||
|
||
AudioRecord record = new AudioRecord(AudioSource.MIC, SAMPLING_RATE, | ||
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, mBufferSize); | ||
record.startRecording(); | ||
|
||
while (shouldContinue()) { | ||
record.read(mAudioBuffer, 0, mBufferSize / 2); | ||
mWaveformView.updateAudioData(mAudioBuffer); | ||
updateDecibelLevel(); | ||
} | ||
|
||
record.stop(); | ||
record.release(); | ||
} | ||
|
||
/** | ||
* Gets a value indicating whether the thread should continue running. | ||
* | ||
* @return true if the thread should continue running or false if it should stop | ||
*/ | ||
private synchronized boolean shouldContinue() { | ||
return mShouldContinue; | ||
} | ||
|
||
/** Notifies the thread that it should stop running at the next opportunity. */ | ||
public synchronized void stopRunning() { | ||
mShouldContinue = false; | ||
} | ||
|
||
/** | ||
* Computes the decibel level of the current sound buffer and updates the appropriate text | ||
* view. | ||
*/ | ||
private void updateDecibelLevel() { | ||
// Compute the root-mean-squared of the sound buffer and then apply the formula for | ||
// computing the decibel level, 20 * log_10(rms). This is an uncalibrated calculation | ||
// that assumes no noise in the samples; with 16-bit recording, it can range from | ||
// -90 dB to 0 dB. | ||
double sum = 0; | ||
|
||
for (short rawSample : mAudioBuffer) { | ||
double sample = rawSample / 32768.0; | ||
sum += sample * sample; | ||
} | ||
|
||
double rms = Math.sqrt(sum / mAudioBuffer.length); | ||
final double db = 20 * Math.log10(rms); | ||
|
||
// Update the text view on the main thread. | ||
mDecibelView.post(new Runnable() { | ||
@Override | ||
public void run() { | ||
mDecibelView.setText(String.format(mDecibelFormat, db)); | ||
} | ||
}); | ||
} | ||
} | ||
} |
Oops, something went wrong.