DSPRelated.com
Forums

spectral smoothing in Matlab

Started by Unknown August 6, 2003
I'm trying to write a function for spectral smoothing using the signal's
cepstrum in Matlab.

Here's what I have:

voice	- a voice signal, 8192 samples long
win	- a right window, 8192 samples long, with a variable cutoff:

1 |_____________
  |              \
  |               \
  |                \
0 |_________________\____________________
  1                 N                 8192


N is set to 1024 for now.
I calculate the real cepstrum of the voice signal:

	v_ceps = real(ifft(log(abs(fft(voice)))));

which I then multiply element-wise with my window:

	v_ceps = v_ceps .* win;

transforming this back _should_ give me a smoothed spectrum.

	smooth_spec = abs(fft(v_ceps));

The problem is, it doesn't work. The output isn't smooth and it doesn't
look similar to the original voice spectrum. Where did I go wrong?
I can't see any error in the algorithm nor the implementation.

Roman


PS: if you know any other good algortithms for spectral smoothing
(constant bandwidth preferred), go right ahead! :-)
Roman Katzer wrote:
> I'm trying to write a function for spectral smoothing using the signal's > cepstrum in Matlab. > > Here's what I have: > > voice - a voice signal, 8192 samples long > win - a right window, 8192 samples long, with a variable cutoff: > > 1 |_____________ > | \ > | \ > | \ > 0 |_________________\____________________ > 1 N 8192 > > > N is set to 1024 for now. > I calculate the real cepstrum of the voice signal: > > v_ceps = real(ifft(log(abs(fft(voice))))); > > which I then multiply element-wise with my window: > > v_ceps = v_ceps .* win; > > transforming this back _should_ give me a smoothed spectrum. > > smooth_spec = abs(fft(v_ceps)); > > The problem is, it doesn't work. The output isn't smooth and it doesn't > look similar to the original voice spectrum. Where did I go wrong? > I can't see any error in the algorithm nor the implementation. > > Roman > > > PS: if you know any other good algortithms for spectral smoothing > (constant bandwidth preferred), go right ahead! :-)
Roman: I think the convolution should be something like this: V = fft(voice); H = fft(win); VH = ifft( V .* H ); Good luck, OUP
"Roman Katzer" <usenet2213@reztak.de> wrote in message
news:och2jv4rpt5394eq87k9fd7hd9ke71845b@4ax.com...
> I'm trying to write a function for spectral smoothing using the signal's > cepstrum in Matlab. > > Here's what I have: > > voice - a voice signal, 8192 samples long > win - a right window, 8192 samples long, with a variable cutoff: > > 1 |_____________ > | \ > | \ > | \ > 0 |_________________\____________________ > 1 N 8192 > > > N is set to 1024 for now. > I calculate the real cepstrum of the voice signal: > > v_ceps = real(ifft(log(abs(fft(voice))))); > > which I then multiply element-wise with my window: > > v_ceps = v_ceps .* win; > > transforming this back _should_ give me a smoothed spectrum. > > smooth_spec = abs(fft(v_ceps)); > > The problem is, it doesn't work. The output isn't smooth and it doesn't > look similar to the original voice spectrum. Where did I go wrong? > I can't see any error in the algorithm nor the implementation. > > Roman
What is a "right window"? Fred
"Roman Katzer" <usenet2213@reztak.de> wrote in message
news:och2jv4rpt5394eq87k9fd7hd9ke71845b@4ax.com...
> I'm trying to write a function for spectral smoothing using the signal's > cepstrum in Matlab. > > Here's what I have: > > voice - a voice signal, 8192 samples long > win - a right window, 8192 samples long, with a variable cutoff: > > 1 |_____________ > | \ > | \ > | \ > 0 |_________________\____________________ > 1 N 8192 > > > N is set to 1024 for now. > I calculate the real cepstrum of the voice signal: > > v_ceps = real(ifft(log(abs(fft(voice))))); > > which I then multiply element-wise with my window: > > v_ceps = v_ceps .* win; > > transforming this back _should_ give me a smoothed spectrum. > > smooth_spec = abs(fft(v_ceps)); > > The problem is, it doesn't work. The output isn't smooth and it doesn't > look similar to the original voice spectrum. Where did I go wrong? > I can't see any error in the algorithm nor the implementation. >
Well, without knowing exactly what the "right window" is, here are some thoughts: You probably do want to apply a window to the original time epoch of 8192 samples. After windowing, extend it with zeros by some large factor like 4 or 8 perhaps, ending with a number of samples that's a power of 2 - for convenience in using the FFT. Now FFT the windowed and extended sequence. Then real(ifft(log(abs()))) Now you have the real part of the complex cepstrum. Components at high times in the cepstrum correspond to delays that have contributed a FIR-like filtering process to the original signal when it was formed. These cause frequency fluctuations in the spectrum. That is, if this is a good model for the signal generation process. Example: old recordings were made by playing music in front of a horn. The horn had a diaphragm driving a stylus at the small diameter end. The horn was like an "echo pipe". So, this model matches this kind of recording signal generation process. Now, multiply the real part of the cepstrum with a window that deletes the high-time components. Now, fft the result to get the log magnitude smoothed spectrum. At least I think that's an appropriate description of what you might be trying to do. More sophisticated extension would attempt to remove the echo effects from the original time signal. But, that's not what you were asking to do. Fred
Hi OUP,

On Wed, 06 Aug 2003 17:36:25 -0500, One Usenet Poster wrote:
>I think the convolution should be something like this:
... but I'm not trying to convolute :) Roman
Hi Fred,

On Wed, 6 Aug 2003 21:00:44 -0700, Fred Marshall wrote:
>What is a "right window"?
maybe my terminology is misleading. I mean the right half of a (hann) window, appended to a sequence of ones and followed by a sequence of zeros. It looks close to something like what I tried to show with ASCII characters below:
>> win - a right window, 8192 samples long, with a variable cutoff: >> >> 1 |_____________ >> | \ >> | \ >> | \ >> 0 |_________________\____________________ >> 1 N 8192
Roman
Roman Katzer wrote:
> Hi OUP, > > On Wed, 06 Aug 2003 17:36:25 -0500, One Usenet Poster wrote: > >>I think the convolution should be something like this: > > > ... but I'm not trying to convolute :) > > Roman
Roman: The operation z = ifft( fft(x) .* fft(y) ) is the convolution (circular) of x and y. OUP
On Thu, 07 Aug 2003 09:47:51 -0500, One Usenet Poster wrote:

>The operation z = ifft( fft(x) .* fft(y) ) is the convolution (circular) >of x and y.
Yes, but what I'm doing is z = fft( real(ifft(log(abs(fft(x))))) .* y ) I'm confused. This is not convolution, is it? Roman
Roman Katzer <usenet2213@reztak.de> wrote in message news:<och2jv4rpt5394eq87k9fd7hd9ke71845b@4ax.com>...
> I'm trying to write a function for spectral smoothing using the signal's > cepstrum in Matlab. > > Here's what I have: > > voice - a voice signal, 8192 samples long > win - a right window, 8192 samples long, with a variable cutoff: > > 1 |_____________ > | \ > | \ > | \ > 0 |_________________\____________________ > 1 N 8192 > > > N is set to 1024 for now. > I calculate the real cepstrum of the voice signal: > > v_ceps = real(ifft(log(abs(fft(voice))))); > > which I then multiply element-wise with my window: > > v_ceps = v_ceps .* win; > > transforming this back _should_ give me a smoothed spectrum. > > smooth_spec = abs(fft(v_ceps)); > > The problem is, it doesn't work. The output isn't smooth and it doesn't > look similar to the original voice spectrum. Where did I go wrong? > I can't see any error in the algorithm nor the implementation. > > Roman > > > PS: if you know any other good algortithms for spectral smoothing > (constant bandwidth preferred), go right ahead! :-)
The problem is that you are ignoring the negative frequencies in the spectrum. Your window should be as follows 1 |_____________ ____________ | \ / | \ / | \ / 0 |_________________\____/_______________ 1 N (8194-N) 8192 Then everything will work. Do the following with your window. Assuming your window is a row vector win(8194-N:8192) = fliplr(win(2:N)); This way you will include the negative frequencies as well. What you are doing NOW amounts to doing a single sideband filtering.
"Roman Katzer" <usenet2213@reztak.de> wrote in message
news:och2jv4rpt5394eq87k9fd7hd9ke71845b@4ax.com...
> I'm trying to write a function for spectral smoothing using the signal's > cepstrum in Matlab. > > Here's what I have: > > voice - a voice signal, 8192 samples long > win - a right window, 8192 samples long, with a variable cutoff: > > 1 |_____________ > | \ > | \ > | \ > 0 |_________________\____________________ > 1 N 8192 > > > N is set to 1024 for now. > I calculate the real cepstrum of the voice signal: > > v_ceps = real(ifft(log(abs(fft(voice))))); > > which I then multiply element-wise with my window: > > v_ceps = v_ceps .* win; > > transforming this back _should_ give me a smoothed spectrum. > > smooth_spec = abs(fft(v_ceps));
This is not the inverse cepstrum. Dirk
> > The problem is, it doesn't work. The output isn't smooth and it doesn't > look similar to the original voice spectrum. Where did I go wrong? > I can't see any error in the algorithm nor the implementation. > > Roman > > > PS: if you know any other good algortithms for spectral smoothing > (constant bandwidth preferred), go right ahead! :-)