Identifying dominant frequency in recorded sound in Android
I'm trying to convert the Python program located at
https://github.com/rraval/pied-piper/blob/master/decode.py
to an Android Java file.
The first step is to identify the dominant frequency. I have written the following Java program to do that
private class RecordAudio
extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... paramVarArgs)
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
byte Data = new byte[bufferSizeInBytes];
AudioRecord audioRecorder = new AudioRecord(audioSource,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
audioRecorder.startRecording();
boolean isRecording = true;
while (isRecording)
audioRecorder.read(Data, 0, Data.length);
fftPrint(Data, bufferSizeInBytes);
return null;
boolean fftPrint(byte waveArray, int bufferSizeInBytes)
double HANDSHAKE_START_HZ = 8192;
double HANDSHAKE_END_HZ = 8192 + 512;
int len = waveArray.length;
double waveTransformReal = new double[len];
double waveTransformImg = new double[len];
for (int i = 0; i < len; i++)
waveTransformReal[i] = waveArray[i]; //copy of original
waveTransformImg[i] = waveArray[i]; //FFT transformed below
RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
p.ft(waveTransformImg);
//Calculating abs
double abs = new double[len];
for (int i = 0; i < len; i++)
abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
//calculating maxIndex
int maxIndex = 0;
for (int i = 0; i < len; i++)
if (abs[i] > abs[maxIndex])
maxIndex = i;
double dominantFrequency = (maxIndex * 44100) / len;
if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));
if (match(dominantFrequency, HANDSHAKE_START_HZ))
Log.i("Handshake start:", "FOUND START");
if (match(dominantFrequency, HANDSHAKE_END_HZ))
Log.i("Handshake end:", "FOUND END");
return true;
return false;
boolean match(double freq1, double freq2)
return (Math.abs(freq1 - freq2) < 20);
Note: RealDoubleFFT is from ca.uol.aig.fftpack
Am not sure if I have done it right. I'm getting the frequencies printed in the Logcat, but they are not finding the HANDSHAKE_START_HZ, which is present in the audio being played. What am I doing wrong?
java audio signal-processing fft pcm
add a comment |
I'm trying to convert the Python program located at
https://github.com/rraval/pied-piper/blob/master/decode.py
to an Android Java file.
The first step is to identify the dominant frequency. I have written the following Java program to do that
private class RecordAudio
extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... paramVarArgs)
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
byte Data = new byte[bufferSizeInBytes];
AudioRecord audioRecorder = new AudioRecord(audioSource,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
audioRecorder.startRecording();
boolean isRecording = true;
while (isRecording)
audioRecorder.read(Data, 0, Data.length);
fftPrint(Data, bufferSizeInBytes);
return null;
boolean fftPrint(byte waveArray, int bufferSizeInBytes)
double HANDSHAKE_START_HZ = 8192;
double HANDSHAKE_END_HZ = 8192 + 512;
int len = waveArray.length;
double waveTransformReal = new double[len];
double waveTransformImg = new double[len];
for (int i = 0; i < len; i++)
waveTransformReal[i] = waveArray[i]; //copy of original
waveTransformImg[i] = waveArray[i]; //FFT transformed below
RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
p.ft(waveTransformImg);
//Calculating abs
double abs = new double[len];
for (int i = 0; i < len; i++)
abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
//calculating maxIndex
int maxIndex = 0;
for (int i = 0; i < len; i++)
if (abs[i] > abs[maxIndex])
maxIndex = i;
double dominantFrequency = (maxIndex * 44100) / len;
if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));
if (match(dominantFrequency, HANDSHAKE_START_HZ))
Log.i("Handshake start:", "FOUND START");
if (match(dominantFrequency, HANDSHAKE_END_HZ))
Log.i("Handshake end:", "FOUND END");
return true;
return false;
boolean match(double freq1, double freq2)
return (Math.abs(freq1 - freq2) < 20);
Note: RealDoubleFFT is from ca.uol.aig.fftpack
Am not sure if I have done it right. I'm getting the frequencies printed in the Logcat, but they are not finding the HANDSHAKE_START_HZ, which is present in the audio being played. What am I doing wrong?
java audio signal-processing fft pcm
add a comment |
I'm trying to convert the Python program located at
https://github.com/rraval/pied-piper/blob/master/decode.py
to an Android Java file.
The first step is to identify the dominant frequency. I have written the following Java program to do that
private class RecordAudio
extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... paramVarArgs)
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
byte Data = new byte[bufferSizeInBytes];
AudioRecord audioRecorder = new AudioRecord(audioSource,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
audioRecorder.startRecording();
boolean isRecording = true;
while (isRecording)
audioRecorder.read(Data, 0, Data.length);
fftPrint(Data, bufferSizeInBytes);
return null;
boolean fftPrint(byte waveArray, int bufferSizeInBytes)
double HANDSHAKE_START_HZ = 8192;
double HANDSHAKE_END_HZ = 8192 + 512;
int len = waveArray.length;
double waveTransformReal = new double[len];
double waveTransformImg = new double[len];
for (int i = 0; i < len; i++)
waveTransformReal[i] = waveArray[i]; //copy of original
waveTransformImg[i] = waveArray[i]; //FFT transformed below
RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
p.ft(waveTransformImg);
//Calculating abs
double abs = new double[len];
for (int i = 0; i < len; i++)
abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
//calculating maxIndex
int maxIndex = 0;
for (int i = 0; i < len; i++)
if (abs[i] > abs[maxIndex])
maxIndex = i;
double dominantFrequency = (maxIndex * 44100) / len;
if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));
if (match(dominantFrequency, HANDSHAKE_START_HZ))
Log.i("Handshake start:", "FOUND START");
if (match(dominantFrequency, HANDSHAKE_END_HZ))
Log.i("Handshake end:", "FOUND END");
return true;
return false;
boolean match(double freq1, double freq2)
return (Math.abs(freq1 - freq2) < 20);
Note: RealDoubleFFT is from ca.uol.aig.fftpack
Am not sure if I have done it right. I'm getting the frequencies printed in the Logcat, but they are not finding the HANDSHAKE_START_HZ, which is present in the audio being played. What am I doing wrong?
java audio signal-processing fft pcm
I'm trying to convert the Python program located at
https://github.com/rraval/pied-piper/blob/master/decode.py
to an Android Java file.
The first step is to identify the dominant frequency. I have written the following Java program to do that
private class RecordAudio
extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... paramVarArgs)
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
byte Data = new byte[bufferSizeInBytes];
AudioRecord audioRecorder = new AudioRecord(audioSource,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
audioRecorder.startRecording();
boolean isRecording = true;
while (isRecording)
audioRecorder.read(Data, 0, Data.length);
fftPrint(Data, bufferSizeInBytes);
return null;
boolean fftPrint(byte waveArray, int bufferSizeInBytes)
double HANDSHAKE_START_HZ = 8192;
double HANDSHAKE_END_HZ = 8192 + 512;
int len = waveArray.length;
double waveTransformReal = new double[len];
double waveTransformImg = new double[len];
for (int i = 0; i < len; i++)
waveTransformReal[i] = waveArray[i]; //copy of original
waveTransformImg[i] = waveArray[i]; //FFT transformed below
RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
p.ft(waveTransformImg);
//Calculating abs
double abs = new double[len];
for (int i = 0; i < len; i++)
abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
//calculating maxIndex
int maxIndex = 0;
for (int i = 0; i < len; i++)
if (abs[i] > abs[maxIndex])
maxIndex = i;
double dominantFrequency = (maxIndex * 44100) / len;
if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));
if (match(dominantFrequency, HANDSHAKE_START_HZ))
Log.i("Handshake start:", "FOUND START");
if (match(dominantFrequency, HANDSHAKE_END_HZ))
Log.i("Handshake end:", "FOUND END");
return true;
return false;
boolean match(double freq1, double freq2)
return (Math.abs(freq1 - freq2) < 20);
Note: RealDoubleFFT is from ca.uol.aig.fftpack
Am not sure if I have done it right. I'm getting the frequencies printed in the Logcat, but they are not finding the HANDSHAKE_START_HZ, which is present in the audio being played. What am I doing wrong?
java audio signal-processing fft pcm
java audio signal-processing fft pcm
edited Nov 14 '18 at 17:23
Paul R
177k24298458
177k24298458
asked Nov 14 '18 at 16:49
ArunArun
2,17332446
2,17332446
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Note that the frequency resolution of a FFT magnitude peak depends on the length of the FFT (and the window, etc.). This length is not specified or constrained in your code, so you won't know whether it is even possible for any FFT result bin to be within 20 Hz of your target frequencies.
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305123%2fidentifying-dominant-frequency-in-recorded-sound-in-android%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Note that the frequency resolution of a FFT magnitude peak depends on the length of the FFT (and the window, etc.). This length is not specified or constrained in your code, so you won't know whether it is even possible for any FFT result bin to be within 20 Hz of your target frequencies.
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
add a comment |
Note that the frequency resolution of a FFT magnitude peak depends on the length of the FFT (and the window, etc.). This length is not specified or constrained in your code, so you won't know whether it is even possible for any FFT result bin to be within 20 Hz of your target frequencies.
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
add a comment |
Note that the frequency resolution of a FFT magnitude peak depends on the length of the FFT (and the window, etc.). This length is not specified or constrained in your code, so you won't know whether it is even possible for any FFT result bin to be within 20 Hz of your target frequencies.
Note that the frequency resolution of a FFT magnitude peak depends on the length of the FFT (and the window, etc.). This length is not specified or constrained in your code, so you won't know whether it is even possible for any FFT result bin to be within 20 Hz of your target frequencies.
answered Nov 16 '18 at 16:27
hotpaw2hotpaw2
61.5k971128
61.5k971128
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
add a comment |
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
Thanks for the answer @hotpaw2, I'm completely new to sound and I managed to write the above code by reading a lot on the net. I did hardcode the bufferSizeInBytes ro 4096. But still did not see the expired output. Each time I run this program and play the same sound, I get different dominant frequencies for each chunk. Can you please help by correcting the above code. Many Thanks.
– Arun
Nov 17 '18 at 11:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305123%2fidentifying-dominant-frequency-in-recorded-sound-in-android%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown