Java Audio question - PLEASE HELP

C

cpptutor2000

Could some DSP or Java guru please help me ? I have a simple Java
application that records audio signals and does simple analysis on the
collected data. I am using PCM encoding, with sampling frequency 16000
Hz, 16 bits resolution, single or mono channel, little endian and
signed.

The data is read into a ByteArrayOutputStream and then as soon as I
stop recording, the stream contents are written to a byte array, using
'toByteArray()'. After that, I can get the size of this byte array,
which gives me the total number of bytes collected, keeping in mind
that I am using 16 bit resolution, i.e., each sound sample is 16 bits
long. I am using a software tone generator, with the frequency set at
500.0 Hertz.

Now, from simple DSP principles, we know that if the number of samples
collected is 'n' and the sampling frequency is 'fs', then the time
needed to collect these 'n' samples is n/fs, and the fundamental
frequency recorded is the inverse of this time value.

However, I am only getting frequencies as low as 7 Hz, or 8Hz, which
is just absurd. Could someone please tell me if I am doing something
totally incorrect, or where the flaw in my reasoning is. Any help
would be greatly appreciated. Thanks in advance for your help.
 
V

Vladimir Vassilevsky

Could some DSP or Java guru please help me ? I have a simple Java
application that records audio signals and does simple analysis on the
collected data. I am using PCM encoding, with sampling frequency 16000
Hz, 16 bits resolution, single or mono channel, little endian and
signed.

The data is read into a ByteArrayOutputStream and then as soon as I
stop recording, the stream contents are written to a byte array, using
'toByteArray()'. After that, I can get the size of this byte array,
which gives me the total number of bytes collected, keeping in mind
that I am using 16 bit resolution, i.e., each sound sample is 16 bits
long. I am using a software tone generator, with the frequency set at
500.0 Hertz.

Now, from simple DSP principles, we know that if the number of samples
collected is 'n' and the sampling frequency is 'fs', then the time
needed to collect these 'n' samples is n/fs, and the fundamental
frequency recorded is the inverse of this time value.

However, I am only getting frequencies as low as 7 Hz, or 8Hz, which
is just absurd. Could someone please tell me if I am doing something
totally incorrect, or where the flaw in my reasoning is. Any help
would be greatly appreciated. Thanks in advance for your help.

Once I was asked to make a portable program in Java which should do some
signal processing using the low level waveform I/O.

That appeared to be impossible because of many weird problems (mainly
with the different JVM drivers).

So, don't try to use Java for the signal processing, especially at the
waveform i/o level and in the real time. Java is not for that.


Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com
 
M

Mark Space

Tim said:
Consider that most audio paths are AC coupled, because humans can't hear
much below 40Hz (or 60, or 20, depending on who you ask). Given that, a
7Hz low-frequency cut off is generously low.

That's a good point, actually. Even if Java were a DSP system, which it
isn't, you're still at the mercy of whatever cheap-ass hardware is on
the motherboard of your PC. I doubt its up to even a low-end studio rig.

If you're using some sort of audio equipment run by Java that's not a
PC, then you need to contact the manufacturer, 'cause there's no way
we're going to know more than the maker.
 
V

Vladimir Vassilevsky

Kenneth said:
Can you elaborate on what the problems were. This really shouldn't be a
problem for Java. I just can't imagine why it would be.

The task was a special modem operating via the sound card continuously.
It worked fine in Win32/C++, however they wanted to make it platform
independent in Java, so they could use the same code in Windows and for
the different flavors of Linux. There were problems with the
interruptions of the continuous flow of the waveform data depending on
the particular JVM and the particular drivers.

Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com
 
R

Ron N.

Now, from simple DSP principles, we know that if the number of samples
collected is 'n' and the sampling frequency is 'fs', then the time
needed to collect these 'n' samples is n/fs,

Correct. You have a sample window covering n/fs units
of time.
and the fundamental
frequency recorded is the inverse of this time value.

The fundamental frequency recorded depends on the contents
of the actual data, not merely this time value. What does
depend on 1/(n/fs), the inverse of your time value, is the
frequency spacing between successive bins of a DFT/FFT
performed on a sample window of that given length in time
(perhaps proportional to a form of frequency "resolution").

Are you calling some sort of frequency analysis routine
in Java? What is the form of the input and the result?
(scalar or complex vector, data type, data packing, and
etc.)


IMHO. YMMV.
 
A

Arne Vajhøj

Kenneth said:
That's strange. I could see garbage collection being a problem, but one
would think that such things have a sufficient buffer to make short
delays inconsequential. I guess not.

GC is very efficient but had poor real time characteristics.

Often the problems can be resolved by tuning the GC via the many
JVM parameters to do so.

Arne
 
V

Vladimir Vassilevsky

Arne said:
GC is very efficient but had poor real time characteristics.

Often the problems can be resolved by tuning the GC via the many
JVM parameters to do so.

Exactly. To make it work, I had to tweak many not so obvious parameters
depending on the particular OS, JVM and drivers. That broke the whole
idea of being independent from the platform.


Vladimir Vassilevsky
DSP and Mixed Signal Design Consultant
http://www.abvolt.com
 
A

Arne Vajhøj

Vladimir said:
Exactly. To make it work, I had to tweak many not so obvious parameters
depending on the particular OS, JVM and drivers. That broke the whole
idea of being independent from the platform.

You did not have to change the code or even rebuild just the
modify the configuration.

It happen - also for other problem domains than real time.

Arne
 
C

cpptutor2000

With reference to all the postings I am sorry I have caused confusion
about what I meant by the 'fundamental frequency' etc., May I give a
simple example?

For a given signal being sampled for analysis, the number of points
obtained and the time between samples combine to determine the total
length of time taken to examine the signal. The following definitions
apply:
fs = sample rate in Hz
dT = 1/fs = interval between samples
N = number of samples taken
T = N x dT = total time period

f1 = 1/T = frequency of the first harmonic in Hz
Keeping these points in mind, I have found that f1 in my case is
around 7 Hz. I am NOT measuring 7 Hz. If I were to take an FFT of the
collected data, then I can expect to get peaks that are harmonics of 7
Hz. That is if I were to detect if the 500.0 Hz signal of the tone
generator was being picked up, I would have look for the 500/7
harmonic of 7 Hz. I hope I have made myself clear about what I am
trying to do.


[...]
Now, from simple DSP principles, we know that if the number of samples
collected is 'n' and the sampling frequency is 'fs', then the time
needed to collect these 'n' samples is n/fs, and the fundamental
frequency recorded is the inverse of this time value.

What's the difference between "sampling frequency" and "fundamental
frequency"? If "fs" is your sampling frequency, then "fs/n" (i.e. "the
inverse of this time value") is a meaningless "per second" value, because
you've removed the "samples" part of the formula.

For example, let's consider a sampling rate of 10 Hz. If you have 10
samples, then your "fs/n" value is "1/second". But if you have 20
samples, without changing the actual sampling rate, your "fs/n" value is
"0.5/second" or "1/(2 seconds)". The actual sampling rate hasn't changed,
but your calculated value -- whatever it's meant to represent -- is
changing.

Obviously lengthing the amount of time so that you can get more samples
doesn't actually change the sampling rate. So if you're trying to use
that "fs/n" to map back to some sort of useful number related to the rate
at which you're sampling, or an audio frequency that you can record, it's
not going to actually do that. "fs/n" is an arbitrary value that is
simply the reciprocal of the number of seconds over which you
recorded...it has nothing to do with the underlying nature of the data
you've recorded, other than being a direct (albeit inverse) measure of the
time duration of the recording.
However, I am only getting frequencies as low as 7 Hz, or 8Hz, which
is just absurd. Could someone please tell me if I am doing something
totally incorrect, or where the flaw in my reasoning is. Any help
would be greatly appreciated. Thanks in advance for your help.

Perhaps you could be more specific about how you're doing the recording.
A concise-but-complete code sample would not be unreasonable here. That
would allow us to precisely know just how you're capturing the audio data,
as well as how you're calculating your frequencies.

From your paragraph about "fundamental frequency", I think there's a
possibility that you're simply not calculating the "frequency" correctly.
You should first be more clear about what frequency it is you really want
to calculate (are you looking for the sampling frequency here?). And you
should show the code you're using to do that calculation.

Also, "PCM" is by itself somewhat ambiguous. There are some PCM formats
that do some rudimentary compression, by encoding each sample as a
difference from the previous sample (and there are multiple variations on
that technique).

If your frequency calculation is correct (which hasn't been shown to be
true yet), and you can take the bytes you saved, group them in twos and
send them back out to an audio playback interface that takes raw,
uncompressed samples and they sound correct, then I'd agree something's
fishy. But I think it's more likely that either the calculation is simply
wrong, or that if you treat those bytes as raw, uncompressed samples,
you'll get garbage trying to play them back.

In other words, I think it's more likely there's a mistake on your part
than that there's something fishy going on. But then, I get the
impression you know that. :) So really, the key here is for you to
provide enough information for someone to explain what your mistake is.
So far, you haven't.

Pete
 
R

Ron N.

With reference to all the postings I am sorry I have caused confusion
about what I meant by the 'fundamental frequency' etc., May I give a
simple example?

For a given signal being sampled for analysis, the number of points
obtained and the time between samples combine to determine the total
length of time taken to examine the signal. The following definitions
apply:
fs = sample rate in Hz
dT = 1/fs = interval between samples
N = number of samples taken
T = N x dT = total time period

f1 = 1/T = frequency of the first harmonic in Hz
Keeping these points in mind, I have found that f1 in my case is
around 7 Hz. I am NOT measuring 7 Hz. If I were to take an FFT of the
collected data, then I can expect to get peaks that are harmonics of 7
Hz. That is if I were to detect if the 500.0 Hz signal of the tone
generator was being picked up, I would have look for the 500/7
harmonic of 7 Hz. I hope I have made myself clear about what I am
trying to do.

You are using non-standard DSP vocabulary. 500 Hz is your
fundamental, not 7 Hz. 7 Hz might be your DFT bin separation,
bin resolution, or spacing.

You also never answered whether you tried plotting your
data after the type conversion to make sure you didn't
clip or wrap it.
 
C

cpptutor2000

You also never answered whether you tried plotting your
data after the type conversion to make sure you didn't
clip or wrap it.

I did plot the data, after the type conversion. I find the following
(typical data sample length 2048 doubles):
1. a few spikes at the start - most probably due to a large DC offset
being introduced somewhere.
2. a large sequence of zeros - about 250 - 300 samples long
3. the sinusoidal curve that one would expect - a little bit noisy,
but still okay.
 
C

cpptutor2000

Even (especially) after reading your later post, I don't
understand what you are saying. From your later post, it seems
that 7 Hz is your bin resolution, so the first bin corresponds
to 7 Hz, the 2nd to 14 Hz, etc. Are you saying that you don't
see a spike near bin 71 (500/7)? Perhaps the amplitude of your
injected tone is too low compared to the amplitude of your
other signal (so the spike is there, it's just lost in the
noise). What exactly is the problem?

The problem is, as I mentioned in a posting just before, that when I
plot the data, I see a long sequence of zeros, about 250 - 300 sample
points long, before I see the sinusoidal signal. There are a few sharp
and large spikes at the start, which might be due to DC offset, but I
do not understand the sequence of zeros. The total sample size of the
collected data is 2048.
 
C

cpptutor2000

So if you accumulated twice as many samples, over twice as long, your
fundamental frequency would be halved? That is not sensible.
That is precisely the case. Please check the definitions above. Please
note that f1 is the first harmonic if I were to calculate an FFT with
the collected samples. The fundamental frequency is 500.0 Hz, and
stays that way.
 
R

Ron N.

The problem is, as I mentioned in a posting just before, that when I
plot the data, I see a long sequence of zeros, about 250 - 300 sample
points long, before I see the sinusoidal signal. There are a few sharp
and large spikes at the start, which might be due to DC offset, but I
do not understand the sequence of zeros. The total sample size of the
collected data is 2048.

It could be a data header. Or it could be how long it
takes your mic or ADC to initialize. Why not just ignore
this header or turn-on transient?

Does your sinusoid have roughly balanced positive and
negative values? Or do you have a DC offset of your
sinusoid?
 
A

Andrew Thompson

With reference to all the postings I am sorry I have caused confusion..

One way to 'cut through the c..onfusion' is to post an
SSCCE. More info here
http://sscce.org/

Have one peice of code to generate the tone,
and a second to do the transform.
 
N

Nigel Wade

Lew said:
No, that doesn't make sense. If I recorded a pure 1000 Hz sine wave, that is
the frequency whether I take 44000 samples for one second or 88000 samples
over two seconds. The frequency isn't affected by how long I record it.

The frequency *resolution* is, though. That's what the OP was referring to
[rather obliquely]. The OP mistakenly calls this the fundamental frequency.

The sampling rate determines the bandwidth, and the maximum freq. which you can
capture (Nyquist-Shannon). The overall length (in time, not samples) determines
the frequency resolution (Fourier).
 
D

dbd

Jerry Avins wrote:

(snip)
It does make some sense in the context of the FFT, though.
Since FFT has periodic boundary conditions, the lowest non-zero
frequency could be considered the fundamental.

In the OP's description, 500 Hz is the lowest non-zero frequency :,).
And it is the 'fundamental of the signal', as opposed belonging to the
set of 'fundamental frequencies of the transform', of which zero is
included as a member.

Does anyone have a suggestion for a description of this area of
vocabulary that is:
1) accessible (free, etc.)
2) complete enough for this level of discussion
3) unambiguous
4) at a suitable level for the OP?
Those who
apply the FFT to non-periodic signals get what they deserve.

Those who have known how to apply the FFT to non-periodic signals have
made much good use of it.

Dale B. Dalrymple
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top