Single precision conversion errors?

I am creating an audio encoder using splines and the polyval function. I would like to be able to store all the polynomial coefficients as singles. The entire code works fine when the coefficients are stored as doubles. However, if I cast them as singles, their values change and the code breaks. I thought the break was coming from the polyval function, so I scratched it and evaluated the polynomials with my own code. The singles still have weird values though. I've attached the code I've been working with. Can anyone shed any light on how I could use single precision and not have the values change?
warning off all;
clc;
clf;
clear all;
[wave_data, Fs] = wavread('10 ms guitar.wav');
% Set display options for polyfit_constrained
options = optimset('lsqlin');
options = optimset(options, 'Display', 'off');
% Creates file to write to
writefile = 'outfile.dat';
fid = fopen(writefile, 'w');
% Low Pass Filter
fNorm = 16000 / (Fs/2);
[b, a] = butter(10, fNorm, 'low');
wave_data = filtfilt(b, a, wave_data);
differences = diff(wave_data);
flags = [];
xrange = [];
k = 1;
degree = 5;
minpoints = 6;
tic
% For loop plants flags at data index points when derivative changes sign
for i = 1:(length(differences) - 1)
if (differences(i) > 0 && differences (i + 1) < 0)...
|| (differences(i) < 0 && differences (i + 1) > 0)
flags(k) = i + 1;
if k ~= 1 && (flags(k) - flags(k - 1)) < minpoints
k = k;
else
k = k + 1;
end
%if size > 40
end
end
% For loop creates range of x-values and y-values for polynomial fitting
for j = 1:length(flags)
% If statement creates different x and y ranges for the first and last
% windows separately from all other windows
if j == 1
xrange = 1:flags(j);
yrange = wave_data(1:flags(j));
elseif j == length(flags)
xrange = (flags(j - 1) + 1):length(wave_data);
yrange = wave_data((flags(j - 1) + 1):length(wave_data));
else
xrange = (flags(j - 1) + 1):flags(j);
yrange = wave_data((flags(j - 1) + 1):flags(j));
end
polyval_coeffs = polyfit_constrained(xrange, yrange, degree, options)
s_polyval_coeffs = single(polyval_coeffs)
s_xrange = single(xrange);
ys = [];
yd = [];
for i=1:length(xrange)
x = xrange(i);
s_temp_y = s_polyval_coeffs(1)*x*x*x*x*x + s_polyval_coeffs(2)*x*x*x*x + s_polyval_coeffs(3)*x*x*x + s_polyval_coeffs(4)*x*x + s_polyval_coeffs(5)*x + s_polyval_coeffs(6);
ys = [ys; s_temp_y];
%x = xrange(i);
d_temp_y = polyval_coeffs(1)*x*x*x*x*x + polyval_coeffs(2)*x*x*x*x + polyval_coeffs(3)*x*x*x + polyval_coeffs(4)*x*x + polyval_coeffs(5)*x + polyval_coeffs(6);
yd = [yd; d_temp_y];
end
subplot(3,1,1);
plot(wave_data);
subplot(3,1,2);
plot(xrange, yd);
hold all;
subplot(3,1,3);
plot(xrange, ys);
hold all;
fwrite(fid, polyval_coeffs, 'double');
fwrite(fid, length(xrange), 'uint8');
end
fclose(fid);
toc

2 Kommentare

Geoff
Geoff am 27 Mär. 2012
Can you be more specific about what you mean by "the code breaks"? Also, are you processing your values as singles, or do you always do the calculations as double and then cast the result to single at the end?
Jacob
Jacob am 27 Mär. 2012
I always do the calculations as doubles and then cast at the end. Is there a better solution?
Also, when using doubles the audio quality is much better and the graph looks identical to the input. When using singles, the audio quality is terrible and all the polynomials seem to be pushed to straight lines when looking at the graph. Does that make more sense?

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Jan
Jan am 27 Mär. 2012

0 Stimmen

If problem appear in a program, this:
warning off all
is a bad idea. This suppresses warnings if the polynomial fitting is ill-conditioned and a normalization of the input data is recommended. If this happens in your code, using single values can lead to a loss of accuracy.
This:
polyval_coeffs(1)*x*x*x*x*x
is an instable method to evaluate a polynomial. Use the Horner-method instead.

1 Kommentar

Jacob
Jacob am 27 Mär. 2012
I turned the warnings off because printing them slowed the run time down severely. Thanks for the tip though. The only warning I was getting was "Optimization Terminated." Do you think the situation you described is happening?

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Fourier Analysis and Filtering finden Sie in Hilfe-Center und File Exchange

Gefragt:

am 27 Mär. 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by