Modulating ofdm in audio spectrum

Trying to modulate audio with OFDM data.

My fs = 44.1khz, i'm using 64 sub-carriers, but i'm only using 5 sub-carriers for data, so my bandwidth is about 3.445khz. I'm not sure how to properly write the all real data to a wav file and then reconstruct the complex signal when I read it back. Can someone point me where I'm messing up?

Matlab code:

close all
clear all

%fft length
N=64;
NN=1024;

%carrier frequency
fc = 15000;

%create the data to send
qpsk1 = (floor(2*rand(1,2))-.5)/.5 + 1j*(floor(2*rand(1,2))-.5)/.5;
qpsk2 = (floor(2*rand(1,3))-.5)/.5 + 1j*(floor(2*rand(1,3))-.5)/.5;

inputiFFT = [zeros(1,29) qpsk1, 0, qpsk2 zeros(1,29)];
outputiFFT = ifft(inputiFFT,N);

%spin data to carrier
y3 = outputiFFT.*exp(1j*2*pi*15000/44100*(0:length(outputiFFT)-1));
%despin to baseband for sanity check
y4 = y3.*exp(-1j*2*pi*15000/44100*(0:length(y3)-1));

figure
subplot(211)
hold on
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(outputiFFT,NN)))))
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(y3,NN)))))
hold off
title('Data - blue, Data at carrier - r')
subplot(212)
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(y4,NN)))))
title('sanity check down mix')

%upconvert to 15khz and write to wav (all 'real')
towav = real(outputiFFT).*cos(-2*pi*fc/44100*(0:length(outputiFFT)-1)) + imag(outputiFFT).*sin(-2*pi*fc/44100*(0:length(outputiFFT)-1));

%write to wav then read from wave
wavwrite(towav, 44100, 'ofdmTest.wav');

figure
hold on
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(towav,NN)))),'color','b')
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(y3,NN)))),'color','r')
hold off
title('Theoretical data up converted to carrier -r , data written to wav - b')

%convert to I-Q
yRx = (y_wav.*cos(-2*pi*fc/44100*(0:length(outputiFFT)-1)).'+ 1j*y_wav.*sin(-2*pi*fc/44100*(0:length(outputiFFT)-1)).');

figure
hold on
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(yRx.',NN)))),'color','b')
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(y_wav,NN)))),'color','r')
plot((-0.5:1/NN:.5-1/NN)*44100, ((abs(fft(y3,NN)))),'color','g')

hold off
title('yRx -b, data written to wav -r, theoretical - g')

Typically you use Orthogonal Frequency Division Multiplexing (OFDM) with communications. In this context having complex data in the time domain makes sense because the real and imaginary parts of the number represent the inphase and quadrature parts of the signal.

In an audio signal which is what a wav file is used for is only real. As sound is a naturally occurring signal.

I am not sure why you'd want to store the inverse of an FFT in a wav file (listening to it would sound awful). As you've discovered there's no way of guaranteeing that this data is real. You seem to get around this by taking the real part of the output and only writing that to your file.

However, if I assume you need this data stored in a wav file you could store the real and imaginary part in the wav file by interleaving them. You could write something like:

towav = zeros(length(outputiFFT)*2);
towav(1:2:end-1) = real(outputiFFT).*cos(-2*pi*fc/44100*(0:length(outputiFFT)-1));
towav(2:2:end) = imag(outputiFFT).*sin(-2*pi*fc/44100*(0:length(outputiFFT)-1));