Forums

AM demodulation from I/Q file SDRSharp

Started by engrmasood2002 June 16, 2014
I have downloaded SDRSharp AM I/Q wav file from web with following
attributes:
single channel, 
floating point samples 
22050 sample rate.

i got this information about file from audacity software.
The SDRSharp demodulates the samples and generate audio from file when it
is played in  it.
I want to demodulate the same using AM demodulation from my software
written in C++. i am using fromula. i.e. Audio=sqrt( I*I + Q*Q);. 
I am able to read the file through my C++ application and was able to hear
tones similar to what i hear when i open this using vlc or any other media
player, it means i am reading correct but when i apply formula i get
nothing at output just a constant buzz sound. 
Also the floating samples are in range between -1 to 1.
If any one has worked on I/Q files can tell 
1. What i need to do with I/Q data before demodulation?
2. The value of samples are from -1 to 1. do i need to change it, if yes
then how?
3. Do i need to filter I/Q data before demodulation? but i dont know what
to put as cut off frequency of filter and filter be low pass or band pass?
My C++ implementation using portaudio is 

samples_count=sf_readf_float(file,fptr,256);
		if( samples_count==0 )
			break;
		//processing/////////////////////		
		for(int a=0; a<samples_count; a++)
		{	
		dem=sqrt( (*fptr)*(*fptr++) + (*fptr)*(*fptr++) ); //sqrt( I*I+Q*Q);
		*fptr=dem*1.2;
		}
//write to soundcard for output
Pa_WriteStream( g_PAStream, fptr, samples_count );

	 

_____________________________		
Posted through www.DSPRelated.com
On 16.6.14 17:14, engrmasood2002 wrote:
> I have downloaded SDRSharp AM I/Q wav file from web with following > attributes: > single channel, > floating point samples > 22050 sample rate. > > i got this information about file from audacity software. > The SDRSharp demodulates the samples and generate audio from file when it > is played in it. > I want to demodulate the same using AM demodulation from my software > written in C++. i am using fromula. i.e. Audio=sqrt( I*I + Q*Q);. > I am able to read the file through my C++ application and was able to hear > tones similar to what i hear when i open this using vlc or any other media > player, it means i am reading correct but when i apply formula i get > nothing at output just a constant buzz sound. > Also the floating samples are in range between -1 to 1. > If any one has worked on I/Q files can tell > 1. What i need to do with I/Q data before demodulation? > 2. The value of samples are from -1 to 1. do i need to change it, if yes > then how? > 3. Do i need to filter I/Q data before demodulation? but i dont know what > to put as cut off frequency of filter and filter be low pass or band pass? > My C++ implementation using portaudio is > > samples_count=sf_readf_float(file,fptr,256); > if( samples_count==0 ) > break; > //processing///////////////////// > for(int a=0; a<samples_count; a++) > { > dem=sqrt( (*fptr)*(*fptr++) + (*fptr)*(*fptr++) ); //sqrt( I*I+Q*Q); > *fptr=dem*1.2; > } > //write to soundcard for output > Pa_WriteStream( g_PAStream, fptr, samples_count );
Your C++ code is not too good: 1. There is no guarantee of the order of picking the samples and incrementing the pointer. 2. The final assignment destroys the first value of next sample. Try this: for (int a = 0; a < samples_count; a++) { i = *iptr++; q = *iptr++; *optr++ = 1.2 * sqrt(i * i + q * q); } Please remember that you should remove the DC component of the decoded AM, if an audio signal is required. The cut-off frequency depends on your modulating signal. -- Tauno Voipio
i have modified code but still no luck.
	samples_count=sf_readf_float(file,fptr,256); 
		if( samples_count<256 )
			break;
		//processing/////////////////////		
		newfptr=fptr;
		float out[512],final[512];
		memcpy(out,fptr,samples_count);
		int j=0;
		for(int a=0; (a<	samples_count/4);a+=0)// a++)
		{	
			float x,y;
			x=(out[a]*out[a++]);
			y=(out[a]*out[a++]);
			final[j++]=sqrt(  x + y  );			
		}
		
		////////////ends//////////////
 Pa_WriteStream( g_PAStream, final, samples_count ); 
How it can be known whether this IQ samples are ready for demodulation or
do they need to be low pass filtered first?
Also how can i remove dc component?

>On 16.6.14 17:14, engrmasood2002 wrote: >> I have downloaded SDRSharp AM I/Q wav file from web with following >> attributes: >> single channel, >> floating point samples >> 22050 sample rate. >> >> i got this information about file from audacity software. >> The SDRSharp demodulates the samples and generate audio from file when
it
>> is played in it. >> I want to demodulate the same using AM demodulation from my software >> written in C++. i am using fromula. i.e. Audio=sqrt( I*I + Q*Q);. >> I am able to read the file through my C++ application and was able to
hear
>> tones similar to what i hear when i open this using vlc or any other
media
>> player, it means i am reading correct but when i apply formula i get >> nothing at output just a constant buzz sound. >> Also the floating samples are in range between -1 to 1. >> If any one has worked on I/Q files can tell >> 1. What i need to do with I/Q data before demodulation? >> 2. The value of samples are from -1 to 1. do i need to change it, if
yes
>> then how? >> 3. Do i need to filter I/Q data before demodulation? but i dont know
what
>> to put as cut off frequency of filter and filter be low pass or band
pass?
>> My C++ implementation using portaudio is >> >> samples_count=sf_readf_float(file,fptr,256); >> if( samples_count==0 ) >> break; >> //processing///////////////////// >> for(int a=0; a<samples_count; a++) >> { >> dem=sqrt( (*fptr)*(*fptr++) + (*fptr)*(*fptr++) ); //sqrt( I*I+Q*Q); >> *fptr=dem*1.2; >> } >> //write to soundcard for output >> Pa_WriteStream( g_PAStream, fptr, samples_count ); > >Your C++ code is not too good: > >1. There is no guarantee of the order of picking the samples and > incrementing the pointer. > >2. The final assignment destroys the first value of next sample. > >Try this: > > for (int a = 0; a < samples_count; a++) > { > i = *iptr++; > q = *iptr++; > *optr++ = 1.2 * sqrt(i * i + q * q); > } > >Please remember that you should remove the DC component of >the decoded AM, if an audio signal is required. The cut-off >frequency depends on your modulating signal. > >-- > >Tauno Voipio > >
_____________________________ Posted through www.DSPRelated.com
On 16.6.14 21:57, engrmasood2002 wrote:
> i have modified code but still no luck. > samples_count=sf_readf_float(file,fptr,256); > if( samples_count<256 ) > break; > //processing///////////////////// > newfptr=fptr; > float out[512],final[512]; > memcpy(out,fptr,samples_count); > int j=0; > for(int a=0; (a< samples_count/4);a+=0)// a++) > { > float x,y; > x=(out[a]*out[a++]); > y=(out[a]*out[a++]); > final[j++]=sqrt( x + y ); > } > > ////////////ends////////////// > Pa_WriteStream( g_PAStream, final, samples_count ); > How it can be known whether this IQ samples are ready for demodulation or > do they need to be low pass filtered first? > Also how can i remove dc component?
1. memcpy() copies bytes (octets), not elements. Your copy is probably short. 2. The construct out[a]*out[a++] is not guaranteed to execute in the order you think. 3. Did you notice that the output is only half as long as the input? 4. DC component removal is done with a high-pass filter. There are special constructs for it in the literature. -- -TV
>2. The construct out[a]*out[a++] is not guaranteed to > execute in the order you think.
BTW, a modern C compiler will throw a warning for this and a dozen other popular mistakes, but it's usually disabled by default. Use switch -Wall or equivalent, highly recommended. _____________________________ Posted through www.DSPRelated.com
Finally i was able to decode the AM and extracted audio but there is dc
component that needs to be resolved. the problem was with memcpy function,
i was doing something wrong. 
Thanks guys for help.

I have another question regarding sample rate conversion.
The file i decoded was I/Q wav file with 22050 sample rate, i processed the
data at the same sample rate and played the audio through soundcard at the
same rate (22050) and all was fine except dc component.
Now i have another file that has I/Q data stored at much higher rate
arround 200K sample rate. 
Now even if i convert down to 22050 sample rate for demodulation how can i
play demodulated audio at the original sample rate i.e 200k . My soundcard
does not support 200k sample rate.  Does file recorded and audio playing
sample rate needs to be the same?

Thanks

>>2. The construct out[a]*out[a++] is not guaranteed to >> execute in the order you think. > >BTW, a modern C compiler will throw a warning for this and a dozen other >popular mistakes, but it's usually disabled by default. Use switch -Wall
or
>equivalent, highly recommended. > > >_____________________________ >Posted through www.DSPRelated.com >
_____________________________ Posted through www.DSPRelated.com
engrmasood2002 <100558@dsprelated> wrote:
> Finally i was able to decode the AM and extracted audio but there is dc > component that needs to be resolved. the problem was with memcpy function, > i was doing something wrong. > Thanks guys for help.
Are the values twos complement, but you are assuming unsigned, or vice versa? In that case, it isn't memcpy(), but the type of the variables you are copying from/to. -- glen
>engrmasood2002 <100558@dsprelated> wrote: >> Finally i was able to decode the AM and extracted audio but there is dc >> component that needs to be resolved. the problem was with memcpy
function,
>> i was doing something wrong. >> Thanks guys for help. > >Are the values twos complement, but you are assuming unsigned, or >vice versa? > >In that case, it isn't memcpy(), but the type of the variables you >are copying from/to. > >-- glen >
samples read from file are float (32 bit) _____________________________ Posted through www.DSPRelated.com