FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > DSP

DSP comp.dsp newsgroup, mailing list

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 08-01-2007, 08:31 PM
KWhat4
Guest
 
Posts: n/a
Default Sample rate conversion help

I am very new to dsp in general and I am attempting to convert 16khz
PCM stream (byte array) to 8khz stream (byte array) in Java. I have
figured out that I can copy over every other frame from the 16khz
stream to the 8khz one but I get what I think is called dithering? My
question are the following:

How do I clean up the audio so it sounds close to normal?

Is there a better way todo this insted of copying some ratio of
frames?

Should I really be using PCM or is some other format more effective/
easier/faster?

Are there some example snipits to do this sort of thing? (Java / C /
Sudo)


Thanks in advance.

Reply With Quote
  #2 (permalink)  
Old 08-01-2007, 10:54 PM
Erik de Castro Lopo
Guest
 
Posts: n/a
Default Re: Sample rate conversion help

KWhat4 wrote:

> I am very new to dsp in general and I am attempting to convert 16khz
> PCM stream (byte array) to 8khz stream (byte array) in Java.


I assume your audio is 16 bit PCM. You need to operate on it as such.

> I have
> figured out that I can copy over every other frame from the 16khz
> stream to the 8khz one


That s effectively zero-order hold resampling. It will not sound
good.

> but I get what I think is called dithering?


No, its called aliasing. Dithering is something else.

http://en.wikipedia.org/wiki/Aliasing
http://en.wikipedia.org/wiki/Dithering

> My
> question are the following:
>
> How do I clean up the audio so it sounds close to normal?


Once you audio has aliasing noise it is not really possible to clean
it up again (the eggs cannot be unscrambled). What you need to do
is go back to the clean signal and resample it correctly.

> Is there a better way todo this insted of copying some ratio of
> frames?


Yes, for your particular case, you need to apply a low pass filter
that blocks frequencies higher than 4 kHz and then dropping every
second sample will sound just fine.

The more general case is much more complicate.

> Are there some example snipits to do this sort of thing? (Java / C /
> Sudo)


I am the author of a high quality audio resampler realeased under the
terms of the GNU General Public Licence:

http://www.mega-nerd.com/SRC/

Commercial use licenses are also available at reasonable rates.

HTH,
Erik
--
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
BSD: A psychoactive drug, popular in the 80s, probably developed at UC
Berkeley or thereabouts. Similar in many ways to the prescription-only
medication called "System V", but infinitely more useful. (Or, at least,
more fun.) The full chemical name is "Berkeley Standard Distribution".
Reply With Quote
  #3 (permalink)  
Old 08-02-2007, 04:27 AM
Ron N.
Guest
 
Posts: n/a
Default Re: Sample rate conversion help

On Aug 1, 11:31 am, KWhat4 <heispsycho...@gmail.com> wrote:
> I am very new to dsp in general and I am attempting to convert 16khz
> PCM stream (byte array) to 8khz stream (byte array) in Java. I have
> figured out that I can copy over every other frame from the 16khz
> stream to the 8khz one but I get what I think is called dithering?


Aliasing. Your original 16k sample/sec stream probably
contained frequency content from 20 Hz or so to nearly
8 kHz. If so and you didn't do any filtering, then your
8k sample/sec stream will contain not only 0 to 4 kHz
sound, but also 4 to 8 kHz sounds folded down in frequency
right on top of and mixed up with the 0 to 4 kHz sound.
So before you decimate (reduce the sample rate by throwing
away samples) you need to low pass filter so that there
is very little content at or above half the new sample
rate (or you can filter as you decimate in one step).

> My question are the following:
>
> How do I clean up the audio so it sounds close to normal?


You need to filter before decimating. Your "dithered"
sound already has noise mixed in that can't be removed
(without reference to the original signal).

> Is there a better way todo this insted of copying some ratio of
> frames?


Copying a ratio of frames will work if each channel of
the signal has been appropriately low pass filtered beforehand
or is during the copy. You have to filter each channel
separately, so you may have to decompose and recompose
the frames before/after filtering.

If you don't care about optimization, then the filtering
can be done in only a few dozen lines of code.
Here's some untested, quick and dirty code (in Basic !)
which might filter one channel, and even interpolate if
needed:

---cut here---
rem - QDSS Windowed Sinc ReSampling subroutine in Basic
rem
rem : x = new sample point location (relative to old indexes)
rem (e.g. every other integer for 0.5x decimation)
rem : indat = original data array
rem : alim = size of data array
rem : fmax = low pass filter cutoff frequency
rem : fs = sample rate
rem : wnwdth = width of windowed sinc used as the low pass filter
rem - resamp() returns a filtered new sample point

sub resamp(x, indat, alim, fmax, fs, wnwdth)
r_g = 2 * fmax / fs : rem Calc gain correction factor
r_y = 0
for r_i = -wnwdth/2 to (wnwdth/2)-1 : rem For 1 window width
r_j = int(x + r_i) : rem Calc input sample index
: rem calculate von Hann Window. Scale and calculate Sinc
r_w = 0.5 - 0.5 * cos(2*pi*(0.5 + (r_j - x)/wnwdth))
r_a = 2*pi*(r_j - x)*fmax/fs
r_snc = 1 : if (r_a <> 0) then r_snc = sin(r_a)/r_a
if (r_j >= 0) and (r_j < alim) then
r_y = r_y + r_g * r_w * r_snc * indat(r_j)
endif
next r_i
resamp = r_y : rem Return new filtered sample
end sub

rem * Note that fmax should be less than half of fs, and less
rem than half of new_fs (the reciprocal of the x step size).
rem * Filter quality increases with a larger window width.
rem The wider the window, the closer fmax can approach half
rem of fs or new_fs.
rem * Note that several operations inside the FOR loop can be
rem precalculated.
rem * There are more optimal windows than the von Hann window.
rem * Note that if the x step size is rational the same Window
rem and Sinc values will be recalculated repeatedly; therefore
rem these values can either be cached, or precalculated and
rem stored in a table; or interpolated from a smaller
rem precalculated table; or computed with a low-order
rem polynomial fit to each lobe between zero crossings
rem of the windowed sinc. (Performance optimization is
rem left as an exercise for the student).

rem Ron Nicholson's QDSS ReSampler cookbook recipe
rem QDSS = Quick, Dirty, Simple and Short
rem Copyright 2007 Ronald H. Nicholson Jr.
rem Version 0.1 - 2007-Aug-01
rem No warranties implied. Error checking, optimization, and
rem quality assessment of the "results" is left as an exercise
rem for the student.
rem (consider this code Open Source under a BSD style license)
rem IMHO. YMMV. http://www.nicholson.com/rhn/dsp.html

Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Sample Rate conversion naebad DSP 19 11-26-2006 08:55 PM
About asynchronous sample rate conversion nagual.hsu DSP 13 03-20-2006 08:27 AM
Sample rate conversion doubt jaac DSP 12 01-06-2005 06:35 PM
Sample Rate Conversion (Downsampling) Jaime Andrés Aranguren Cardona DSP 26 12-18-2004 05:14 AM
Sample Rate Conversion Confusion Morgan P?lsson DSP 7 06-29-2004 08:47 PM


All times are GMT +1. The time now is 01:56 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved