├── cricket
├── data.txt
├── inf.mat
├── aeiou.wav
├── cricket.wav
├── triplet.wav
├── cricket1.wav
├── Huffmann English.xls
├── detect.m
├── encode_cricket.m
├── createpacket.m
├── huffencode.m
├── decode_cricket.m
└── huffdecode.m
├── ask-simple-java
├── jon.txt
├── test.txt
├── foo.wav
├── jon.wav
├── test.wav
├── Constants.java
├── AudioBuffer.java
├── ArrayUtils.java
├── MicrophoneListener.java
├── Main.java
├── StreamDecoder.java
├── Encoder.java
├── AudioUtils.java
└── Decoder.java
├── cricket-android
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── main.xml
├── bin
│ └── DigitalVoices-CricketAndroid.apk
├── src
│ └── com
│ │ └── jonas
│ │ └── CricketAndroid
│ │ ├── test.wav
│ │ ├── AudioUtils.java
│ │ ├── PlayThread.java
│ │ ├── AudioBuffer.java
│ │ ├── Loopback.java
│ │ ├── Constants.java
│ │ ├── ArrayUtils.java
│ │ ├── MicrophoneListener.java
│ │ ├── StreamDecoder.java
│ │ ├── Huffman.java
│ │ ├── Decoder.java
│ │ ├── Encoder.java
│ │ └── Main.java
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── .classpath
├── default.properties
├── .project
├── gen
│ └── com
│ │ └── jonas
│ │ └── CricketAndroid
│ │ └── R.java
└── AndroidManifest.xml
├── ask-simple-android
├── bin
│ └── ask-simple-android.apk
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── main.xml
├── src
│ └── com
│ │ └── jarkman
│ │ └── ASKSimpleAndroid
│ │ ├── test.wav
│ │ ├── PlayThread.java
│ │ ├── Constants.java
│ │ ├── AudioBuffer.java
│ │ ├── Loopback.java
│ │ ├── ArrayUtils.java
│ │ ├── MicrophoneListener.java
│ │ ├── AudioUtils.java
│ │ ├── Encoder.java
│ │ ├── StreamDecoder.java
│ │ ├── Main.java
│ │ └── Decoder.java
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── .classpath
├── default.properties
├── .project
└── AndroidManifest.xml
└── README.txt
/cricket/data.txt:
--------------------------------------------------------------------------------
1 | AEIOU.
--------------------------------------------------------------------------------
/ask-simple-java/jon.txt:
--------------------------------------------------------------------------------
1 | J O N
--------------------------------------------------------------------------------
/ask-simple-java/test.txt:
--------------------------------------------------------------------------------
1 | :) Hello Bill!
2 |
3 |
--------------------------------------------------------------------------------
/cricket/inf.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/inf.mat
--------------------------------------------------------------------------------
/cricket/aeiou.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/aeiou.wav
--------------------------------------------------------------------------------
/cricket/cricket.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/cricket.wav
--------------------------------------------------------------------------------
/cricket/triplet.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/triplet.wav
--------------------------------------------------------------------------------
/cricket/cricket1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/cricket1.wav
--------------------------------------------------------------------------------
/ask-simple-java/foo.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-java/foo.wav
--------------------------------------------------------------------------------
/ask-simple-java/jon.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-java/jon.wav
--------------------------------------------------------------------------------
/ask-simple-java/test.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-java/test.wav
--------------------------------------------------------------------------------
/cricket/Huffmann English.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket/Huffmann English.xls
--------------------------------------------------------------------------------
/cricket-android/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket-android/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/cricket-android/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket-android/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/cricket-android/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket-android/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/ask-simple-android/bin/ask-simple-android.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-android/bin/ask-simple-android.apk
--------------------------------------------------------------------------------
/ask-simple-android/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-android/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/ask-simple-android/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-android/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/ask-simple-android/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-android/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/cricket-android/bin/DigitalVoices-CricketAndroid.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket-android/bin/DigitalVoices-CricketAndroid.apk
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/test.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/cricket-android/src/com/jonas/CricketAndroid/test.wav
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/test.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diva/digital-voices/HEAD/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/test.wav
--------------------------------------------------------------------------------
/ask-simple-android/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World, Main!
4 | ASKSimpleAndroid
5 |
6 |
--------------------------------------------------------------------------------
/ask-simple-android/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Wed Apr 07 09:06:44 BST 2010
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
4 | org.eclipse.jdt.core.compiler.compliance=1.5
5 | org.eclipse.jdt.core.compiler.source=1.5
6 |
--------------------------------------------------------------------------------
/cricket-android/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Wed Apr 07 09:06:44 BST 2010
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
4 | org.eclipse.jdt.core.compiler.compliance=1.5
5 | org.eclipse.jdt.core.compiler.source=1.5
6 |
--------------------------------------------------------------------------------
/cricket-android/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World, Main!
4 | CricketAndroid
5 | text to chirp
6 |
7 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | Welcome to the Digital Voices project!
2 |
3 | Here you find a collection of codecs for sending and
4 | receiving audio signals over regular mics and speakers.
5 | The code is licensed under the MIT license.
6 |
7 | If you want to improve and/or add to this collection,
8 | please drop me a line.
9 |
--------------------------------------------------------------------------------
/cricket-android/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ask-simple-android/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ask-simple-android/default.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "build.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-6
12 | # Indicates whether an apk should be generated for each density.
13 | split.density=false
14 |
--------------------------------------------------------------------------------
/cricket-android/default.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "build.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-8
12 | # Indicates whether an apk should be generated for each density.
13 | split.density=false
14 |
--------------------------------------------------------------------------------
/cricket/detect.m:
--------------------------------------------------------------------------------
1 | function correlation = detect(signal, Freq, fs)
2 |
3 | % constants
4 | floatToByteShift = 128;
5 |
6 | % y = e^(ju) = cos(u) + j*sin(u)
7 | u = 2*pi*Freq/fs;
8 |
9 | % realSum = real(signal * u) .* signal;
10 | % imaginarySum = imag(signal * u) .* signal;
11 | %
12 | % realAvg = mean(realSum);
13 | % imaginaryAvg = mean(imaginarySum);
14 |
15 | realSum = 0;
16 | imaginarySum = 0;
17 | for i = 1:length(signal)
18 | realSum = realSum + (cos(i*u) * signal(i));
19 | imaginarySum = imaginarySum + (sin(i*u) * signal(i));
20 | end
21 |
22 | realAvg = realSum/length(signal);
23 | imaginaryAvg = imaginarySum/length(signal);
24 |
25 | correlation = sqrt(power(realAvg, 2) + power(imaginaryAvg, 2));
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/AudioUtils.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | /**
4 | * Copyright 2012 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | * (Modified by Jonas Michel, 2012)
8 | */
9 |
10 |
11 |
12 | import java.io.ByteArrayOutputStream;
13 | import java.io.IOException;
14 | import java.util.ArrayList;
15 |
16 |
17 | /**
18 | *
19 | * @author jrm
20 | */
21 |
22 | public class AudioUtils {
23 |
24 | public static void performData(byte[] data)
25 | throws IOException {
26 |
27 | PlayThread p = new PlayThread( data );
28 |
29 | }
30 |
31 | public static void performString(String string) throws IOException {
32 | ArrayList huffencoded = Huffman.huffencode(string);
33 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
34 | Encoder.encodeCricket(huffencoded, baos);
35 | performData(baos.toByteArray());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/ask-simple-android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ASKSimpleAndroid
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/cricket-android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | DigitalVoices-CricketAndroid
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ask-simple-android/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
17 |
18 |
20 |
21 |
23 |
24 |
--------------------------------------------------------------------------------
/cricket-android/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
17 |
18 |
20 |
21 |
23 |
24 |
--------------------------------------------------------------------------------
/cricket-android/gen/com/jonas/CricketAndroid/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.jonas.CricketAndroid;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int icon=0x7f020000;
15 | }
16 | public static final class id {
17 | public static final int ButtonListen=0x7f050002;
18 | public static final int ButtonPlay=0x7f050001;
19 | public static final int EditTextToPlay=0x7f050000;
20 | public static final int TextListen=0x7f050004;
21 | public static final int TextStatus=0x7f050003;
22 | }
23 | public static final class layout {
24 | public static final int main=0x7f030000;
25 | }
26 | public static final class string {
27 | public static final int app_name=0x7f040001;
28 | public static final int default_text=0x7f040002;
29 | public static final int hello=0x7f040000;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ask-simple-android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/cricket-android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/PlayThread.java:
--------------------------------------------------------------------------------
1 | package com.jarkman.ASKSimpleAndroid;
2 |
3 |
4 | import android.media.AudioFormat;
5 | import android.media.AudioManager;
6 | import android.media.AudioTrack;
7 |
8 | public class PlayThread extends Thread{
9 |
10 | public boolean isPlaying = true;
11 | private byte[] buffer;
12 |
13 | public PlayThread( byte[] b )
14 | {
15 | buffer = new byte[b.length * 2];
16 |
17 | // convert from 8 bit per sample to little-endian 16 bit per sample, IOW 16-bit PCM
18 | int i, j;
19 | for(i=0, j =0; i < b.length; i++, j += 2)
20 | {
21 | buffer[j] = 0;
22 | buffer[j+1] = b[i];
23 | }
24 |
25 |
26 | start();
27 | }
28 |
29 | public void run()
30 | {
31 |
32 | isPlaying = true;
33 |
34 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
35 |
36 | AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,
37 | (int) Encoder.kSamplingFrequency,
38 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
39 | AudioFormat.ENCODING_PCM_16BIT, // ENCODING_PCM_8BIT sounds very scratchy, so we use 16 bit and double up the data
40 | buffer.length,
41 | AudioTrack.MODE_STREAM);
42 |
43 | atrack.setPlaybackRate((int) Encoder.kSamplingFrequency);
44 |
45 |
46 |
47 | atrack.play();
48 |
49 | try {
50 | atrack.write(buffer, 0, buffer.length);
51 | } catch (Exception e) {
52 |
53 | e.printStackTrace();
54 | }
55 |
56 |
57 | atrack.stop();
58 | }
59 |
60 | public void stopLoop()
61 | {
62 | isPlaying = false;
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/PlayThread.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | /**
4 | * Copyright 2012 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | */
8 |
9 | import android.media.AudioFormat;
10 | import android.media.AudioManager;
11 | import android.media.AudioTrack;
12 |
13 | public class PlayThread extends Thread{
14 |
15 | public boolean isPlaying = true;
16 | private byte[] buffer;
17 |
18 | public PlayThread( byte[] b )
19 | {
20 | buffer = new byte[b.length * 2];
21 |
22 | // convert from 8 bit per sample to little-endian 16 bit per sample, IOW 16-bit PCM
23 | int i, j;
24 | for(i=0, j =0; i < b.length; i++, j += 2)
25 | {
26 | buffer[j] = 0;
27 | buffer[j+1] = b[i];
28 | }
29 |
30 |
31 | start();
32 | }
33 |
34 | public void run()
35 | {
36 |
37 | isPlaying = true;
38 |
39 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
40 |
41 | AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,
42 | (int) Encoder.kSamplingFrequency,
43 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
44 | AudioFormat.ENCODING_PCM_16BIT, // ENCODING_PCM_8BIT sounds very scratchy, so we use 16 bit and double up the data
45 | buffer.length,
46 | AudioTrack.MODE_STREAM);
47 |
48 | atrack.setPlaybackRate((int) Encoder.kSamplingFrequency);
49 |
50 |
51 |
52 | atrack.play();
53 |
54 | try {
55 | atrack.write(buffer, 0, buffer.length);
56 | } catch (Exception e) {
57 |
58 | e.printStackTrace();
59 | }
60 |
61 |
62 | atrack.stop();
63 | }
64 |
65 | public void stopLoop()
66 | {
67 | isPlaying = false;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/cricket/encode_cricket.m:
--------------------------------------------------------------------------------
1 | % Copyright 2001 by the authors. All rights reserved.
2 | % Authors: Cristina V Lopes (crista at tagide dot com)
3 | % Patricio de la Guardia
4 | %
5 | % Permission is hereby granted, free of charge, to any person obtaining a copy
6 | % of this software and associated documentation files (the "Software"), to deal
7 | % in the Software without restriction, including without limitation the rights
8 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | % copies of the Software, and to permit persons to whom the Software is
10 | % furnished to do so, subject to the following conditions:
11 | %
12 | % The above copyright notice and this permission notice shall be included in
13 | % all copies or substantial portions of the Software.
14 | %
15 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | % THE SOFTWARE.
22 |
23 |
24 | clear all
25 | close all
26 |
27 | fs= 22050;
28 | Freq = 4184;
29 | framelength = 420; %miliseconds
30 | % packetlength = 17; %miliseconds
31 | % silencelength = 22; %miliseconds
32 | FILE = 'data.txt';
33 | [datain, count] = fread(fopen(FILE, 'r'), 'uint8');
34 | % texto = [];
35 | % for k = 1: count
36 | % texto = [texto,char(datain(k))];
37 | % end
38 | info = huffencode(datain);
39 | signal = [];
40 | encoded = [];
41 | for i = 1:4:length(info) - 4
42 | packet = createpacket(info(i:i+4), fs, Freq, framelength);
43 | signal = [signal, packet];
44 | end
45 |
46 | % include a hail and EOT packet
47 | % signal = [createpacket([1 3 3 3], fs, Freq, framelength) signal];
48 | window = hanning(0.1*fs);
49 | time = 0:1/fs:(fs*0.1-1)/fs;
50 | hail = sin(2*pi*time*Freq);
51 | hail = hail.*window';
52 | signal = [hail signal hail];
53 |
54 | %signal = signal + .08*rand(1,length(signal));
55 | plot(signal);
56 | wavwrite(signal/max(abs(signal)),fs,'signal.wav');
57 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/Constants.java:
--------------------------------------------------------------------------------
1 | package com.jarkman.ASKSimpleAndroid;
2 |
3 |
4 | /**
5 | * Copyright 2002 by the authors. All rights reserved.
6 | *
7 | * Authir: Cristina V Lopes
8 | */
9 |
10 | public interface Constants {
11 |
12 | public static final double kLowFrequency = 600; //the lowest frequency used
13 | public static final double kFrequencyStep = 50; //the distance between frequencies
14 |
15 | public static final int kBytesPerDuration = 1; //how wide is the data stream
16 | // (rps - that is, the pre-encoding data stream, not the audio)
17 | // (rps - kFrequencies must be this long)
18 |
19 | public static final int kBitsPerByte = 8; //unlikely to change, I know
20 |
21 | // Amplitude of each frequency in a frame.
22 | public static final double kAmplitude = 0.125d; /* (1/8) */
23 |
24 | // Sampling frequency (number of sample values per second)
25 | public static final double kSamplingFrequency = 11025; //rps - reduced to 11025 from 22050
26 | // to enable the decoder to keep up with the audio on Motorola CLIQ
27 |
28 | // Sound duration of encoded byte (in seconds)
29 | public static final double kDuration = 0.2; // rps - increased from 0.1 to improve reliability on Android
30 |
31 | // Number of samples per duration
32 | public static final int kSamplesPerDuration = (int)(kSamplingFrequency * kDuration);
33 |
34 | //This is used to convert the floats of the encoding to the bytes of the audio
35 | public static final int kFloatToByteShift = 128;
36 |
37 | // The length, in durations, of the key sequence
38 | public static final int kDurationsPerKey = 3;
39 |
40 | //The frequency used in the initial hail of the key
41 | public static final int kHailFrequency = 3000;
42 |
43 | //The frequencies we use for each of the 8 bits
44 | public static final int[] kFrequencies = {1000, //1000
45 | (int)(1000 * (float)27/24), //1125
46 | (int)(1000 * (float)30/24), //1250
47 | (int)(1000 * (float)36/24), //1500
48 | (int)(1000 * (float)40/24), //1666
49 | (int)(1000 * (float)48/24), //2000
50 | (int)(1000 * (float)54/24), //2250
51 | (int)(1000 * (float)60/24)};//2500
52 | }
53 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/AudioBuffer.java:
--------------------------------------------------------------------------------
1 | package com.jarkman.ASKSimpleAndroid;
2 |
3 | /**
4 | * Copyright 2002 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | */
8 |
9 | import java.util.*;
10 | import java.io.*;
11 |
12 | /**
13 | * A thread safe buffer for audio samples
14 | * NOTE: This has no hard limits for memory usage
15 | *
16 | * @author CVL
17 | */
18 | public class AudioBuffer {
19 | private ByteArrayOutputStream baos = new ByteArrayOutputStream();
20 | private Object lock = new Object();
21 |
22 | public AudioBuffer(){};
23 |
24 | /**
25 | * @param input an array to write to the end of the buffer
26 | */
27 | public synchronized void write(byte[] input)
28 | throws IOException {
29 | baos.write(input);
30 | }
31 |
32 | /**
33 | * @param input the source array
34 | * @param offset the offset into the array from which to start copying
35 | * @param length the length to copy
36 | */
37 | public synchronized void write(byte[] input, int offset, int length)
38 | throws IOException {
39 | baos.write(input, offset, length);
40 | }
41 |
42 | /**
43 | * @param n the number of bytes to try to read (nondestructively)
44 | * @return if the buffer.size >= n, return the requested byte array, otherwise null
45 | *
46 | * NOTE: THIS DOES NOT REMOVE BYTES FROM THE BUFFER
47 | */
48 | public synchronized byte[] read(int n){
49 | if(baos.size() < n){
50 | return null;
51 | }
52 | byte[] result = ArrayUtils.subarray(baos.toByteArray(), 0, n);
53 | return result;
54 | }
55 |
56 | /**
57 | * @param n the number of bytes to remove from the buffer.
58 | * If n > buffer.size, it has the same effect as n = buffer.size.
59 | */
60 | public synchronized void delete(int n)
61 | throws IOException {
62 | if(n <= 0){
63 | return;
64 | }
65 | if(baos.size() < n){
66 | baos.reset();
67 | return;
68 | }
69 | byte[] buff = ArrayUtils.subarray(baos.toByteArray(), n - 1, baos.size() - n);
70 | baos.reset();
71 | baos.write(buff);
72 | }
73 |
74 | /**
75 | * @return the current size of the buffer
76 | */
77 | public synchronized int size(){
78 | int size = 0;
79 | size = baos.size();
80 | return size;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/AudioBuffer.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | /**
4 | * Copyright 2012 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | */
8 |
9 | import java.io.ByteArrayOutputStream;
10 | import java.io.IOException;
11 |
12 | /**
13 | * A thread safe buffer for audio samples
14 | * NOTE: This has no hard limits for memory usage
15 | *
16 | * @author CVL
17 | */
18 | public class AudioBuffer {
19 | private ByteArrayOutputStream baos = new ByteArrayOutputStream();
20 | private Object lock = new Object();
21 |
22 | public AudioBuffer(){};
23 |
24 | /**
25 | * @param input an array to write to the end of the buffer
26 | */
27 | public synchronized void write(byte[] input)
28 | throws IOException {
29 | baos.write(input);
30 | }
31 |
32 | /**
33 | * @param input the source array
34 | * @param offset the offset into the array from which to start copying
35 | * @param length the length to copy
36 | */
37 | public synchronized void write(byte[] input, int offset, int length)
38 | throws IOException {
39 | baos.write(input, offset, length);
40 | }
41 |
42 | /**
43 | * @param n the number of bytes to try to read (nondestructively)
44 | * @return if the buffer.size >= n, return the requested byte array, otherwise null
45 | *
46 | * NOTE: THIS DOES NOT REMOVE BYTES FROM THE BUFFER
47 | */
48 | public synchronized byte[] read(int n){
49 | if(baos.size() < n){
50 | return null;
51 | }
52 | byte[] result = ArrayUtils.subarray(baos.toByteArray(), 0, n);
53 | return result;
54 | }
55 |
56 | /**
57 | * @param n the number of bytes to remove from the buffer.
58 | * If n > buffer.size, it has the same effect as n = buffer.size.
59 | */
60 | public synchronized void delete(int n)
61 | throws IOException {
62 | if(n <= 0){
63 | return;
64 | }
65 | if(baos.size() < n){
66 | baos.reset();
67 | return;
68 | }
69 | byte[] buff = ArrayUtils.subarray(baos.toByteArray(), n - 1, baos.size() - n);
70 | baos.reset();
71 | baos.write(buff);
72 | }
73 |
74 | /**
75 | * @return the current size of the buffer
76 | */
77 | public synchronized int size(){
78 | int size = 0;
79 | size = baos.size();
80 | return size;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/Loopback.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | import android.media.AudioFormat;
4 | import android.media.AudioManager;
5 | import android.media.AudioRecord;
6 | import android.media.AudioTrack;
7 | import android.media.MediaRecorder;
8 |
9 | // Simple microphone/speaker loopback test to check Andoid audio APIs are working
10 |
11 | public class Loopback extends Thread{
12 |
13 | public boolean isRecording = true;
14 |
15 | public void run()
16 | {
17 | // from http://www.mail-archive.com/android-developers@googlegroups.com/msg76498.html
18 |
19 | isRecording = true;
20 |
21 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
22 |
23 | int buffersize = AudioRecord.getMinBufferSize(11025,
24 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
25 | AudioFormat.ENCODING_PCM_16BIT);
26 |
27 | if( buffersize < 1 )
28 | {
29 | // parameters not supported by hardware, probably
30 | isRecording = false;
31 | return;
32 | }
33 |
34 | AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
35 | 11025,
36 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
37 | AudioFormat.ENCODING_PCM_16BIT,
38 | buffersize);
39 |
40 | AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,
41 | 11025,
42 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
43 | AudioFormat.ENCODING_PCM_16BIT,
44 | buffersize, //ba.size(),
45 | AudioTrack.MODE_STREAM);
46 |
47 | atrack.setPlaybackRate(11025);
48 |
49 | byte[] buffer = new byte[buffersize];
50 |
51 | arec.startRecording();
52 | atrack.play();
53 |
54 | while(isRecording) {
55 | arec.read(buffer, 0, buffersize);
56 | try {
57 | atrack.write(buffer, 0, buffer.length);
58 | } catch (Exception e) {
59 |
60 | e.printStackTrace();
61 | }
62 | }
63 |
64 | arec.stop();
65 | atrack.stop();
66 | }
67 |
68 | public void stopLoop()
69 | {
70 | isRecording = false;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/Loopback.java:
--------------------------------------------------------------------------------
1 | package com.jarkman.ASKSimpleAndroid;
2 |
3 | import java.io.IOException;
4 |
5 | import android.media.AudioFormat;
6 | import android.media.AudioManager;
7 | import android.media.AudioRecord;
8 | import android.media.AudioTrack;
9 | import android.media.MediaRecorder;
10 |
11 | // Simple microphone/speaker loopback test to check Andoid audio APIs are working
12 |
13 | public class Loopback extends Thread{
14 |
15 | public boolean isRecording = true;
16 |
17 | public void run()
18 | {
19 | // from http://www.mail-archive.com/android-developers@googlegroups.com/msg76498.html
20 |
21 | isRecording = true;
22 |
23 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
24 |
25 | int buffersize = AudioRecord.getMinBufferSize(11025,
26 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
27 | AudioFormat.ENCODING_PCM_16BIT);
28 |
29 | if( buffersize < 1 )
30 | {
31 | // parameters not supported by hardware, probably
32 | isRecording = false;
33 | return;
34 | }
35 |
36 | AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
37 | 11025,
38 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
39 | AudioFormat.ENCODING_PCM_16BIT,
40 | buffersize);
41 |
42 | AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,
43 | 11025,
44 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
45 | AudioFormat.ENCODING_PCM_16BIT,
46 | buffersize, //ba.size(),
47 | AudioTrack.MODE_STREAM);
48 |
49 | atrack.setPlaybackRate(11025);
50 |
51 | byte[] buffer = new byte[buffersize];
52 |
53 | arec.startRecording();
54 | atrack.play();
55 |
56 | while(isRecording) {
57 | arec.read(buffer, 0, buffersize);
58 | try {
59 | atrack.write(buffer, 0, buffer.length);
60 | } catch (Exception e) {
61 |
62 | e.printStackTrace();
63 | }
64 | }
65 |
66 | arec.stop();
67 | atrack.stop();
68 | }
69 |
70 | public void stopLoop()
71 | {
72 | isRecording = false;
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | package com.jarkman.ASKSimpleAndroid;
2 |
3 | /**
4 | * Copyright 2002 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | */
8 |
9 |
10 | /**
11 | * A set of handy array manipulation utilities
12 | * @author CVL
13 | */
14 | public class ArrayUtils {
15 |
16 | /**
17 | * Create a new array of length 'length' and fill it from array 'array'
18 | * @param array the array from which to take the subsection
19 | * @param start the index from which to start the subsection copy
20 | * @param length the length of the returned array.
21 | * @return byte[] of length 'length', padded with zeros if array.length is shorter than 'start' + 'length'
22 | *
23 | * NOTE! if start + length goes beyond the end of array.length, the returned value will be padded with 0s.
24 | */
25 | public static byte[] subarray(byte[] array, int start, int length){
26 | byte[] result = new byte[length];
27 | for(int i=0; (i < length) && (i + start < array.length); i++){
28 | result[i] = array[i + start];
29 | }
30 | return result;
31 | }
32 |
33 | /**
34 | * Converts the input matrix into a single dimensional array by transposing and concatenating the columns
35 | * @param input a 2D array whose columns will be concatenated
36 | * @return the concatenated array
37 | */
38 | public static byte[] concatenate(byte[][] input){
39 | //sum the lengths of the columns
40 | int totalLength = 0;
41 | for(int i = 0; i < input.length; i++){
42 | totalLength += input[i].length;
43 | }
44 | //create the result array
45 | byte[] result = new byte[totalLength];
46 |
47 | //populate the result array
48 | int currentIndex = 0;
49 | for(int i=0; i < input.length; i++){
50 | for(int j = 0; j < input[i].length; j++){
51 | result[currentIndex++] = input[i][j];
52 | }
53 | }
54 | return result;
55 | }
56 |
57 | /**
58 | * @param sequence the array of floats to return as a shifted and clipped array of bytes
59 | * @return byte[i] = sequence[i] * Constants.kFloatToByteShift cast to a byte
60 | * Note!: This doesn't handle cast/conversion issues, so don't use this unless you understand the code
61 | */
62 | public static byte[] getByteArrayFromDoubleArray(double[] sequence){
63 | byte[] result = new byte[sequence.length];
64 | for(int i=0; i < result.length; i++){
65 | result[i] = (byte)((sequence[i] * Constants.kFloatToByteShift) - 1);
66 | }
67 | return result;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/cricket/createpacket.m:
--------------------------------------------------------------------------------
1 | % Copyright 2001 by the authors. All rights reserved.
2 | % Authors: Cristina V Lopes (crista at tagide dot com)
3 | % Patricio de la Guardia
4 | %
5 | % Permission is hereby granted, free of charge, to any person obtaining a copy
6 | % of this software and associated documentation files (the "Software"), to deal
7 | % in the Software without restriction, including without limitation the rights
8 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | % copies of the Software, and to permit persons to whom the Software is
10 | % furnished to do so, subject to the following conditions:
11 | %
12 | % The above copyright notice and this permission notice shall be included in
13 | % all copies or substantial portions of the Software.
14 | %
15 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | % THE SOFTWARE.
22 |
23 | function signal = createpacket(info, fs, Freq, framelength)
24 |
25 | shortsize = 15;
26 | longsize = 24;
27 | bigamplitude = 1;
28 | smallamplitude = 0.5;
29 |
30 | packet = [];
31 | for k = 2:4
32 | switch info(k)
33 | case 1,
34 | packetlength = shortsize;
35 | silencelength = longsize;
36 | amplitude = bigamplitude;
37 | case 2,
38 | packetlength = shortsize;
39 | silencelength = longsize;
40 | amplitude = smallamplitude;
41 | case 3,
42 | packetlength = longsize;
43 | silencelength = shortsize;
44 | amplitude = bigamplitude;
45 | case 4,
46 | packetlength = longsize;
47 | silencelength = shortsize;
48 | amplitude = smallamplitude;
49 | otherwise
50 | displ('Wrong number, only valid 1,2,3,4');break;
51 | end
52 | framesamples = round(fs*framelength/1000);
53 | packetsamples = round(fs*packetlength/1000);
54 | silencesamples = round(fs*silencelength/1000);
55 |
56 | window = hanning(packetsamples);
57 | time = (1:packetsamples)*packetlength/(packetsamples*1000);
58 | smallpacket = amplitude*sin(2*pi*time(1:length(window))*Freq);
59 | smallpacket = smallpacket.*window';
60 | packet = [packet, zeros(1,round(silencesamples)), smallpacket];
61 | end
62 |
63 | signal = [zeros(1,round(fs*(info(1)-1)*(2*shortsize + 1.5*longsize)/1000)), packet];
64 | signal = [signal, zeros(1,framesamples - length(signal))];
65 |
66 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/Constants.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | /**
4 | * Copyright 2012 by the authors. All rights reserved.
5 | *
6 | * Author: Jonas Michel
7 | */
8 |
9 | public interface Constants {
10 |
11 | public static final int kBitsPerByte = 8; //unlikely to change, I know
12 |
13 | // Sampling frequency (number of sample values per second)
14 | public static final double kSamplingFrequency = 22050;
15 |
16 | // Sound duration of encoded byte (in seconds)
17 | public static final double kDuration = 0.2; // increased from 0.1 to improve reliability on Android
18 |
19 | // Number of samples per duration
20 | public static final int kSamplesPerDuration = (int)(kSamplingFrequency * kDuration);
21 |
22 | //This is used to convert the floats of the encoding to the bytes of the audio
23 | public static final int kFloatToByteShift = 128;
24 |
25 | // The length, in durations, of the key sequence
26 | public static final int kDurationsPerKey = 3;
27 |
28 | //The frequency used in the initial hail of the key
29 | public static final int kHailFrequency = 3000;
30 |
31 | // The detection threshold for a hail key
32 | public static final double kKeyDetectionThreshold = 0.20;
33 |
34 | // Hail detection granularities
35 | public static final int kKeyDetectionGranularityCoarse = 400;
36 | public static final int kKeyDetectionGranularityFine = 20;
37 |
38 | // The chirping frequency
39 | public static final int kFrequency = 4184;
40 |
41 | // The length in milliseconds of a frame
42 | public static final int kFrameLength = 420; // ms
43 |
44 | // The number of samples in a frame
45 | public static final int kSamplesPerFrame = (int) Math.round((kSamplingFrequency * kFrameLength) / 1000);
46 |
47 | // The length (width) in milliseconds of "short" and "long" chirps
48 | public static final int kShortSize = (int) Math.round(15); // ms
49 | public static final int kLongSize = (int) Math.round(24*1.5); // ms
50 |
51 | // Aliases for chirp lengths
52 | public static final int kPacketLength = kShortSize; // ms
53 | public static final int kSilenceLength = kLongSize; // ms
54 |
55 | // The amplitudes of "big" and "small" chirps
56 | public static final double kBigAmplitude = 1.0;
57 | public static final double kSmallAmplitude = 0.25;
58 |
59 | // Some heavily used convenience constants
60 | public static final int kSilencePacketLength = (kShortSize + kLongSize);
61 | public static final int kSilencePacketSamples = (int) Math.round((kSamplingFrequency * kSilencePacketLength) / 1000);
62 | public static final int kThreePacketSamples = (int) Math.round((3 * kSamplingFrequency * kSilencePacketLength) / 1000);
63 |
64 | // Chirp decoding thresholds (these may need to be tuned to fit your smartphone)
65 | public static final double kThreshWidth = 16.0;
66 | public static final double kThreshAmplitude = 1.50;
67 | }
68 |
--------------------------------------------------------------------------------
/ask-simple-java/Constants.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2002 by the authors. All rights reserved.
3 | *
4 | * Author: Cristina V Lopes (crista at tagide dot com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
24 | */
25 |
26 | public interface Constants {
27 |
28 | public static final double kLowFrequency = 600; //the lowest frequency used
29 | public static final double kFrequencyStep = 50; //the distance between frequencies
30 |
31 | public static final int kBytesPerDuration = 1; //how wide is the data stream
32 | public static final int kBitsPerByte = 8; //unlikely to change, I know
33 |
34 | // Amplitude of each frequency in a frame.
35 | public static final double kAmplitude = 0.125d; /* (1/8) */
36 |
37 | // Sampling frequency (number of sample values per second)
38 | public static final double kSamplingFrequency = 22050;
39 |
40 | // Sound duration of encoded byte (in seconds)
41 | public static final double kDuration = 0.1;
42 |
43 | // Number of samples per duration
44 | public static final int kSamplesPerDuration = (int)(kSamplingFrequency * kDuration);
45 |
46 | //This is used to convert the floats of the encoding to the bytes of the audio
47 | public static final int kFloatToByteShift = 128;
48 |
49 | // The length, in durations, of the key sequence
50 | public static final int kDurationsPerKey = 3;
51 |
52 | //The frequency used in the initial hail of the key
53 | public static final int kHailFrequency = 3000;
54 |
55 | //The frequencies we use for each of the 8 bits
56 | public static final int[] kFrequencies = {1000, //1000
57 | (int)(1000 * (float)27/24), //1125
58 | (int)(1000 * (float)30/24), //1250
59 | (int)(1000 * (float)36/24), //1500
60 | (int)(1000 * (float)40/24), //1666
61 | (int)(1000 * (float)48/24), //2000
62 | (int)(1000 * (float)54/24), //2250
63 | (int)(1000 * (float)60/24)};//2500
64 | }
65 |
--------------------------------------------------------------------------------
/cricket/huffencode.m:
--------------------------------------------------------------------------------
1 | % Copyright 2001 by the authors. All rights reserved.
2 | % Authors: Cristina V Lopes (crista at tagide dot com)
3 | % Patricio de la Guardia
4 | %
5 | % Permission is hereby granted, free of charge, to any person obtaining a copy
6 | % of this software and associated documentation files (the "Software"), to deal
7 | % in the Software without restriction, including without limitation the rights
8 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | % copies of the Software, and to permit persons to whom the Software is
10 | % furnished to do so, subject to the following conditions:
11 | %
12 | % The above copyright notice and this permission notice shall be included in
13 | % all copies or substantial portions of the Software.
14 | %
15 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | % THE SOFTWARE.
22 |
23 | function output = huffencode(input)
24 | output = [];
25 | for i = 1:length(input)
26 | switch input(i)
27 | case {' ',','}
28 | output = [output, 4];
29 | case {'a','A'}
30 | output = [output,1, 4];
31 | case {'b','B'}
32 | output = [output,2, 4,4,2 ];
33 | case {'c','C'}
34 | output = [output,1,1,3 ];
35 | case {'d','D'}
36 | output = [output,1,1,2 ];
37 | case {'e','E'}
38 | output = [output,1,2 ];
39 | case {'f','F'}
40 | output = [output, 2,4,3];
41 | case {'g','G'}
42 | output = [output, 2,3,2];
43 | case {'h','H'}
44 | output = [output, 3,4];
45 | case {'i','I'}
46 | output = [output,2,2 ];
47 | case {'j','J'}
48 | output = [output, 2,4,2,2];
49 | case {'k','K'}
50 | output = [output, 2,4,4,4];
51 | case {'l','L'}
52 | output = [output, 1,1,1];
53 | case {'m','M'}
54 | output = [output, 2,4,1];
55 | case {'n','N'}
56 | output = [output, 3,1];
57 | case {'o','O'}
58 | output = [output, 2,1];
59 | case {'p','P'}
60 | output = [output, 2,3,1];
61 | case {'q','Q'}
62 | output = [output,2,4,2,3 ];
63 | case {'r','R'}
64 | output = [output, 3,3];
65 | case {'s','S'}
66 | output = [output, 3,2];
67 | case {'t','T'}
68 | output = [output, 1,3];
69 | case {'u','U'}
70 | output = [output, 1,1,4];
71 | case {'v','V'}
72 | output = [output, 2,4,4,3];
73 | case {'w','W'}
74 | output = [output, 2,3,3];
75 | case {'x','X'}
76 | output = [output, 2,4,2,1];
77 | case {'y','Y'}
78 | output = [output, 2,4,4,1];
79 | case {'z','Z'}
80 | output = [output, 2,4,2,4];
81 | case {'.',';'}
82 | output = [output, 2,3,4];
83 |
84 | otherwise
85 | disp('ERROR: Character not known!!');
86 | disp(input(i))
87 | end
88 | end
89 |
90 | output
91 |
--------------------------------------------------------------------------------
/ask-simple-java/AudioBuffer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2002 by the authors. All rights reserved.
3 | *
4 | * Author: Cristina V Lopes (crista at tagide dot com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
24 | */
25 |
26 | import java.util.*;
27 | import java.io.*;
28 |
29 | /**
30 | * A thread safe buffer for audio samples
31 | * NOTE: This has no hard limits for memory usage
32 | *
33 | * @author CVL
34 | */
35 | public class AudioBuffer {
36 | private ByteArrayOutputStream baos = new ByteArrayOutputStream();
37 | private Object lock = new Object();
38 |
39 | public AudioBuffer(){};
40 |
41 | /**
42 | * @param input an array to write to the end of the buffer
43 | */
44 | public synchronized void write(byte[] input)
45 | throws IOException {
46 | baos.write(input);
47 | }
48 |
49 | /**
50 | * @param input the source array
51 | * @param offset the offset into the array from which to start copying
52 | * @param length the length to copy
53 | */
54 | public synchronized void write(byte[] input, int offset, int length)
55 | throws IOException {
56 | baos.write(input, offset, length);
57 | }
58 |
59 | /**
60 | * @param n the number of bytes to try to read (nondestructively)
61 | * @return if the buffer.size >= n, return the requested byte array, otherwise null
62 | *
63 | * NOTE: THIS DOES NOT REMOVE BYTES FROM THE BUFFER
64 | */
65 | public synchronized byte[] read(int n){
66 | if(baos.size() < n){
67 | return null;
68 | }
69 | byte[] result = ArrayUtils.subarray(baos.toByteArray(), 0, n);
70 | return result;
71 | }
72 |
73 | /**
74 | * @param n the number of bytes to remove from the buffer.
75 | * If n > buffer.size, it has the same effect as n = buffer.size.
76 | */
77 | public synchronized void delete(int n)
78 | throws IOException {
79 | if(n <= 0){
80 | return;
81 | }
82 | if(baos.size() < n){
83 | baos.reset();
84 | return;
85 | }
86 | byte[] buff = ArrayUtils.subarray(baos.toByteArray(), n - 1, baos.size() - n);
87 | baos.reset();
88 | baos.write(buff);
89 | }
90 |
91 | /**
92 | * @return the current size of the buffer
93 | */
94 | public synchronized int size(){
95 | int size = 0;
96 | size = baos.size();
97 | return size;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/ask-simple-java/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2002 by the authors. All rights reserved.
3 | *
4 | * Author: Cristina V Lopes (crista at tagide dot com)
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
24 | */
25 |
26 |
27 | /**
28 | * A set of handy array manipulation utilities
29 | * @author CVL
30 | */
31 | public class ArrayUtils {
32 |
33 | /**
34 | * Create a new array of length 'length' and fill it from array 'array'
35 | * @param array the array from which to take the subsection
36 | * @param start the index from which to start the subsection copy
37 | * @param length the length of the returned array.
38 | * @return byte[] of length 'length', padded with zeros if array.length is shorter than 'start' + 'length'
39 | *
40 | * NOTE! if start + length goes beyond the end of array.length, the returned value will be padded with 0s.
41 | */
42 | public static byte[] subarray(byte[] array, int start, int length){
43 | byte[] result = new byte[length];
44 | for(int i=0; (i < length) && (i + start < array.length); i++){
45 | result[i] = array[i + start];
46 | }
47 | return result;
48 | }
49 |
50 | /**
51 | * Converts the input matrix into a single dimensional array by transposing and concatenating the columns
52 | * @param input a 2D array whose columns will be concatenated
53 | * @return the concatenated array
54 | */
55 | public static byte[] concatenate(byte[][] input){
56 | //sum the lengths of the columns
57 | int totalLength = 0;
58 | for(int i = 0; i < input.length; i++){
59 | totalLength += input[i].length;
60 | }
61 | //create the result array
62 | byte[] result = new byte[totalLength];
63 |
64 | //populate the result array
65 | int currentIndex = 0;
66 | for(int i=0; i < input.length; i++){
67 | for(int j = 0; j < input[i].length; j++){
68 | result[currentIndex++] = input[i][j];
69 | }
70 | }
71 | return result;
72 | }
73 |
74 | /**
75 | * @param sequence the array of floats to return as a shifted and clipped array of bytes
76 | * @return byte[i] = sequence[i] * Constants.kFloatToByteShift cast to a byte
77 | * Note!: This doesn't handle cast/conversion issues, so don't use this unless you understand the code
78 | */
79 | public static byte[] getByteArrayFromDoubleArray(double[] sequence){
80 | byte[] result = new byte[sequence.length];
81 | for(int i=0; i < result.length; i++){
82 | result[i] = (byte)((sequence[i] * Constants.kFloatToByteShift) - 1);
83 | }
84 | return result;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/ArrayUtils.java:
--------------------------------------------------------------------------------
1 | package com.jonas.CricketAndroid;
2 |
3 | /**
4 | * Copyright 2012 by the authors. All rights reserved.
5 | *
6 | * Author: Cristina V Lopes
7 | * (Modified by Jonas Michel, 2012)
8 | */
9 |
10 |
11 | /**
12 | * A set of handy array manipulation utilities
13 | * @author CVL
14 | */
15 | public class ArrayUtils {
16 |
17 | /**
18 | * Create a new array of length 'length' and fill it from array 'array'
19 | * @param array the array from which to take the subsection
20 | * @param start the index from which to start the subsection copy
21 | * @param length the length of the returned array.
22 | * @return byte[] of length 'length', padded with zeros if array.length is shorter than 'start' + 'length'
23 | *
24 | * NOTE! if start + length goes beyond the end of array.length, the returned value will be padded with 0s.
25 | */
26 | public static byte[] subarray(byte[] array, int start, int length){
27 | byte[] result = new byte[length];
28 | for(int i=0; (i < length) && (i + start < array.length); i++){
29 | result[i] = array[i + start];
30 | }
31 | return result;
32 | }
33 |
34 | /**
35 | * Converts the input matrix into a single dimensional array by transposing and concatenating the columns
36 | * @param input a 2D array whose columns will be concatenated
37 | * @return the concatenated array
38 | */
39 | public static byte[] concatenate(byte[][] input){
40 | //sum the lengths of the columns
41 | int totalLength = 0;
42 | for(int i = 0; i < input.length; i++){
43 | totalLength += input[i].length;
44 | }
45 | //create the result array
46 | byte[] result = new byte[totalLength];
47 |
48 | //populate the result array
49 | int currentIndex = 0;
50 | for(int i=0; i < input.length; i++){
51 | for(int j = 0; j < input[i].length; j++){
52 | result[currentIndex++] = input[i][j];
53 | }
54 | }
55 | return result;
56 | }
57 |
58 | /**
59 | * @param sequence the array of floats to return as a shifted and clipped array of bytes
60 | * @return byte[i] = sequence[i] * Constants.kFloatToByteShift cast to a byte
61 | * Note!: This doesn't handle cast/conversion issues, so don't use this unless you understand the code
62 | */
63 | public static byte[] getByteArrayFromDoubleArray(double[] sequence){
64 | byte[] result = new byte[sequence.length];
65 | for(int i=0; i < result.length; i++){
66 | result[i] = (byte)((sequence[i] * Constants.kFloatToByteShift) - 1);
67 | }
68 | return result;
69 | }
70 |
71 | /**
72 | * @param sequence the array of bytes to return as an array of doubles
73 | * @return double[i] = sequence[i] / Constants.kFloatToByteShift cast to a byte
74 | * Note!: This doesn't handle cast/conversion issues, so don't use this unless you understand the code
75 | */
76 | public static double[] getDoubleArrayfromByteArray(byte[] sequence) {
77 | double[] result = new double[sequence.length];
78 | for (int i = 0; i < result.length; i++) {
79 | result[i] = (double)(sequence[i]/(double)Constants.kFloatToByteShift);
80 | }
81 | return result;
82 | }
83 |
84 | /**
85 | * @param src the array of doubles to get the slice of
86 | * @param begin the starting index of the slice
87 | * @param end the ending index of the slice
88 | * @return new sliced array
89 | */
90 | public static double[] getSlice(double[] src, int begin, int end) {
91 | double slice[] = new double[end - begin];
92 | for (int i = 0; i < (end - begin); i++) {
93 | slice[i] = src[i + begin];
94 | }
95 | return slice;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/ask-simple-java/MicrophoneListener.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2002 by the authors. All rights reserved.
3 | *
4 | * Author: Cristina V Lopes (crista at tagide dot com)
5 | *
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in
15 | all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | THE SOFTWARE.
24 |
25 | */
26 |
27 | import javax.sound.sampled.*;
28 | import java.io.*;
29 |
30 | /**
31 | * This thread puts bytes from the microphone into the StreamDecoder's buffer.
32 | *
33 | * @author CVL
34 | */
35 | public class MicrophoneListener implements Runnable {
36 |
37 | public static final String kThreadName = "MicrophoneListener";
38 |
39 | private AudioBuffer buffer = null;
40 | private Thread myThread = null;
41 | private Object runLock = new Object();
42 | private boolean running = false;
43 |
44 | /**
45 | * NOTE: This spawns a thread to do the listening and then returns
46 | * @param _buffer the AudioBuffer into which to write the microphone input
47 | */
48 | public MicrophoneListener(AudioBuffer _buffer) {
49 | buffer = _buffer;
50 | myThread = new Thread(this, kThreadName);
51 | myThread.start();
52 | }
53 |
54 | public void run() {
55 | synchronized(runLock){
56 | running = true;
57 | }
58 |
59 | try {
60 | /**
61 | * NOTE: we want buffSize large so that we don't loose samples when the
62 | * StreamDecoder thread kicks in. But we want to read a small number of
63 | * samples at a time, so that StreamDecoder can process them and they get
64 | * freed from the buffer as soon as possible.
65 | * So there's a fine balance going on here between the two threads, and
66 | * if it's not tuned, samples will be lost.
67 | */
68 | int buffSize = 32000;
69 | int buffSizeFraction = 8;
70 | TargetDataLine line = AudioUtils.getTargetDataLine(AudioUtils.kDefaultFormat);
71 | line.open(AudioUtils.kDefaultFormat, buffSize);
72 | System.out.println(Thread.currentThread().getName() + "> bufferSize = " + line.getBufferSize());
73 | ByteArrayOutputStream out = new ByteArrayOutputStream();
74 | byte[] data = new byte[line.getBufferSize() / buffSizeFraction];
75 | int numBytesRead;
76 | line.start();
77 | while(running){
78 | numBytesRead = line.read(data, 0, data.length);
79 | // System.out.println(Thread.currentThread().getName() + "> bytesRead = " + numBytesRead);
80 | buffer.write(data, 0, numBytesRead);
81 | }
82 | line.drain();
83 | line.stop();
84 | line.close();
85 | } catch (Exception e){
86 | System.out.println(e.toString());
87 | }
88 | }
89 |
90 | public void quit(){
91 | synchronized(runLock){
92 | running = false;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/cricket-android/src/com/jonas/CricketAndroid/MicrophoneListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.jonas.CricketAndroid;
3 |
4 | /**
5 | * Copyright 2012 by the authors. All rights reserved.
6 | *
7 | * Author: Cristina V Lopes
8 | */
9 |
10 |
11 | import android.media.AudioFormat;
12 | import android.media.AudioRecord;
13 | import android.media.MediaRecorder;
14 |
15 | /**
16 | * This thread puts bytes from the microphone into the StreamDecoder's buffer.
17 | *
18 | * @author CVL
19 | */
20 | public class MicrophoneListener implements Runnable {
21 |
22 | public static final String kThreadName = "MicrophoneListener";
23 |
24 | private AudioBuffer buffer = null;
25 | private Thread myThread = null;
26 | private Object runLock = new Object();
27 | private boolean running = false;
28 |
29 | /**
30 | * NOTE: This spawns a thread to do the listening and then returns
31 | * @param _buffer the AudioBuffer into which to write the microphone input
32 | */
33 | public MicrophoneListener(AudioBuffer _buffer) {
34 | buffer = _buffer;
35 | myThread = new Thread(this, kThreadName);
36 | myThread.start();
37 | }
38 |
39 |
40 |
41 | public void run() {
42 | synchronized(runLock){
43 | running = true;
44 | }
45 |
46 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
47 |
48 |
49 | try {
50 | /**
51 | * NOTE: we want buffSize large so that we don't loose samples when the
52 | * StreamDecoder thread kicks in. But we want to read a small number of
53 | * samples at a time, so that StreamDecoder can process them and they get
54 | * freed from the buffer as soon as possible.
55 | * So there's a fine balance going on here between the two threads, and
56 | * if it's not tuned, samples will be lost.
57 | */
58 |
59 |
60 | int buffSize = (int) Encoder.kSamplingFrequency
61 | * 2 // 2 seconds in the buffer
62 | * 2; // recording in 16 bit
63 |
64 | int biteSize = ((int) Encoder.kSamplingFrequency ) / 8; // move 1/8 sec of data at a time
65 |
66 | AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
67 | (int) Encoder.kSamplingFrequency, //11025,
68 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
69 | AudioFormat.ENCODING_PCM_16BIT, // must match PlayThread. Tried (and failed) to make ENCODING_PCM_8BIT work on Android
70 | buffSize);
71 | System.out.println(Thread.currentThread().getName() + " is recording");
72 | //ByteArrayOutputStream out = new ByteArrayOutputStream();
73 | byte[] data_16bit = new byte[ biteSize * 2];
74 | byte[] data_8bit = new byte[ biteSize ];
75 |
76 | int numBytesRead;
77 | arec.startRecording();
78 | while(running)
79 | {
80 | numBytesRead = arec.read(data_16bit, 0, data_16bit.length);
81 |
82 | // convert the 16bit we have to read to to 8bit by discarding alternate bytes - PCM is little-endian, so we discard the first byte
83 | int i;
84 | int j;
85 | for( i = 1, j = 0; i < numBytesRead; i += 2, j ++)
86 | data_8bit[j] = data_16bit[i];
87 |
88 | //System.out.println(Thread.currentThread().getName() + "> bytesRead = " + numBytesRead);
89 |
90 | buffer.write(data_8bit, 0, j); //writes into the buffer, which StreamDecoder is eagerly reading from
91 | //buffer.write(data, 0, numBytesRead);
92 |
93 | Thread.yield();
94 | }
95 |
96 | arec.stop();
97 | arec.release();
98 | } catch (Exception e){
99 | System.out.println(e.toString());
100 | }
101 | }
102 |
103 | public void quit(){
104 | synchronized(runLock){
105 | running = false;
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/ask-simple-android/src/com/jarkman/ASKSimpleAndroid/MicrophoneListener.java:
--------------------------------------------------------------------------------
1 |
2 | package com.jarkman.ASKSimpleAndroid;
3 |
4 | /**
5 | * Copyright 2002 by the authors. All rights reserved.
6 | *
7 | * Author: Cristina V Lopes
8 | */
9 |
10 |
11 | import java.io.*;
12 |
13 | import android.media.AudioFormat;
14 | import android.media.AudioRecord;
15 | import android.media.MediaRecorder;
16 |
17 | /**
18 | * This thread puts bytes from the microphone into the StreamDecoder's buffer.
19 | *
20 | * @author CVL
21 | */
22 | public class MicrophoneListener implements Runnable {
23 |
24 | public static final String kThreadName = "MicrophoneListener";
25 |
26 | private AudioBuffer buffer = null;
27 | private Thread myThread = null;
28 | private Object runLock = new Object();
29 | private boolean running = false;
30 |
31 | /**
32 | * NOTE: This spawns a thread to do the listening and then returns
33 | * @param _buffer the AudioBuffer into which to write the microphone input
34 | */
35 | public MicrophoneListener(AudioBuffer _buffer) {
36 | buffer = _buffer;
37 | myThread = new Thread(this, kThreadName);
38 | myThread.start();
39 | }
40 |
41 |
42 |
43 | public void run() {
44 | synchronized(runLock){
45 | running = true;
46 | }
47 |
48 | android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
49 |
50 |
51 | try {
52 | /**
53 | * NOTE: we want buffSize large so that we don't loose samples when the
54 | * StreamDecoder thread kicks in. But we want to read a small number of
55 | * samples at a time, so that StreamDecoder can process them and they get
56 | * freed from the buffer as soon as possible.
57 | * So there's a fine balance going on here between the two threads, and
58 | * if it's not tuned, samples will be lost.
59 | */
60 |
61 |
62 | int buffSize = (int) Encoder.kSamplingFrequency
63 | * 2 // 2 seconds in the buffer
64 | * 2; // recording in 16 bit
65 |
66 | int biteSize = ((int) Encoder.kSamplingFrequency ) / 8; // move 1/8 sec of data at a time
67 |
68 | AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
69 | (int) Encoder.kSamplingFrequency, //11025,
70 | AudioFormat.CHANNEL_CONFIGURATION_MONO,
71 | AudioFormat.ENCODING_PCM_16BIT, // must match PlayThread. Tried (and failed) to make ENCODING_PCM_8BIT work on Android
72 | buffSize);
73 | System.out.println(Thread.currentThread().getName() + " is recording");
74 | //ByteArrayOutputStream out = new ByteArrayOutputStream();
75 | byte[] data_16bit = new byte[ biteSize * 2];
76 | byte[] data_8bit = new byte[ biteSize ];
77 |
78 | int numBytesRead;
79 | arec.startRecording();
80 | while(running)
81 | {
82 | numBytesRead = arec.read(data_16bit, 0, data_16bit.length);
83 |
84 | // convert the 16bit we have to read to to 8bit by discarding alternate bytes - PCM is little-endian, so we discard the first byte
85 | int i;
86 | int j;
87 | for( i = 1, j = 0; i < numBytesRead; i += 2, j ++)
88 | data_8bit[j] = data_16bit[i];
89 |
90 | //System.out.println(Thread.currentThread().getName() + "> bytesRead = " + numBytesRead);
91 |
92 | buffer.write(data_8bit, 0, j); //writes into the buffer, which StreamDecoder is eagerly reading from
93 | //buffer.write(data, 0, numBytesRead);
94 |
95 | Thread.yield();
96 | }
97 |
98 | arec.stop();
99 | arec.release();
100 | } catch (Exception e){
101 | System.out.println(e.toString());
102 | }
103 | }
104 |
105 | public void quit(){
106 | synchronized(runLock){
107 | running = false;
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/cricket/decode_cricket.m:
--------------------------------------------------------------------------------
1 | % Copyright 2001 by the authors. All rights reserved.
2 | % Authors: Cristina V Lopes (crista at tagide dot com)
3 | % Patricio de la Guardia
4 | %
5 | % Permission is hereby granted, free of charge, to any person obtaining a copy
6 | % of this software and associated documentation files (the "Software"), to deal
7 | % in the Software without restriction, including without limitation the rights
8 | % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | % copies of the Software, and to permit persons to whom the Software is
10 | % furnished to do so, subject to the following conditions:
11 | %
12 | % The above copyright notice and this permission notice shall be included in
13 | % all copies or substantial portions of the Software.
14 | %
15 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | % THE SOFTWARE.
22 |
23 | clear all
24 | close all
25 | [signal, fs, nbits] = wavread('signal.wav');
26 |
27 | shortsize = 15;
28 | longsize = 24;
29 | Freq = 4184;
30 | framelength = 420;
31 | packetlength = shortsize;
32 | silencelength = longsize;
33 | silencepacketlength = shortsize + longsize;
34 | silencepacketsamples = round(fs*(shortsize + longsize)/1000);
35 | threepacketsamples = round(fs*3*silencepacketlength/1000);
36 | framesamples = round(fs*framelength/1000);
37 |
38 | output=[];
39 | threshwidth = 9;
40 | threshamplitude = 0.75;
41 |
42 | %here we need to synchronize
43 | window = hanning(0.1*fs);
44 | time = 0:1/fs:(fs*0.1-1)/fs;
45 | hail = exp(sqrt(-1)*2*pi*time*Freq);
46 | hail = hail.*window';
47 | %startindex = synchronize(signal(1:fs*5), hail');
48 | startindex = finddelay(hail', signal);
49 | if startindex == 0
50 | startindex = 1;
51 | end
52 | maxvalue=max(abs(signal(startindex:startindex+length(hail))));
53 | startindex=startindex+length(hail)-1;
54 | % normalize
55 | signal=signal/maxvalue;
56 |
57 | winner = 0;
58 | for i = startindex:framesamples:length(signal)
59 | eot=detect(signal(i:i+length(hail)),Freq,fs);
60 | if (eot > 0.15)
61 | break;
62 | end
63 | maxpower = 0;
64 | %First symbol
65 | for k = 1:4
66 |
67 | beggining = i + round(fs*(k-1)*(2*packetlength + 1.5*silencelength)/1000);
68 | if (beggining + threepacketsamples > length(signal))
69 | signal = [signal; zeros(length(signal)-beggining + threepacketsamples+1, 1)];
70 | end
71 | power = norm(signal(beggining:beggining + threepacketsamples));
72 | %figure(2), plot(signal(beggining:beggining + threepacketsamples)),pause
73 | if power > maxpower
74 | maxpower = power;
75 | winner = k;
76 | end
77 | end
78 | %Second Symbol, we need the possition of the three packets
79 | begg = i + round(fs*(winner-1)*(2*packetlength + 1.5*silencelength)/1000);
80 | for jj = 1:3
81 | currframe = signal(begg + silencepacketsamples*(jj-1):begg + silencepacketsamples*jj);
82 | %figure(2), plot(currframe),pause
83 | amplitude(jj) = abs(max(currframe));
84 | width(jj) = norm(currframe/amplitude(jj));
85 | if width(jj) < threshwidth
86 | if amplitude(jj) < threshamplitude
87 | value(jj) = 2;
88 | else
89 | value(jj) = 1;
90 | end
91 | else %width(jj) >= threshwidth
92 | if amplitude(jj) < threshamplitude
93 | value(jj) = 4;
94 | else
95 | value(jj) = 3;
96 | end
97 | end
98 | end
99 | % plot(signal(begg :begg + silencepacketsamples*3))
100 | % winner
101 | % value
102 | % pause;
103 | output = [output, winner, value];
104 | end
105 | output
106 | text = huffdecode(output)
107 |
--------------------------------------------------------------------------------
/ask-simple-java/Main.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2002 by the authors. All rights reserved.
3 | *
4 | * Author: Cristina V Lopes (crista at tagide dot com)
5 | *
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in
15 | all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | THE SOFTWARE.
24 |
25 | */
26 |
27 | import java.io.*;
28 |
29 | /**
30 | *
This class gives example uses of the digital voices code.