View Single Post
  #5   Report Post  
Old January 11th 10, 02:14 PM posted to rec.radio.amateur.digital.misc
coupe coupe is offline
external usenet poster
 
First recorded activity by RadioBanter: Jan 2010
Posts: 3
Default analizing rf signals

On Dec 1 2009, 9:08*am, "Raymond BARBER"
wrote:
Am trying to write C program to use sound card to input rf signals into
computer and then analise them. Would appreciate help on programming sound
card etc

73
Ray G3NEF


The problem with C, is it is a pretty low level interface to the sound
card. You basically have to build your driver around the library
calls. People have done it, but by the time they get done, they
aren't going to give it away for free. There's a bunch of code out in
the wild, and it is mostly unreadable. The ham radio stuff for linux
basically looks like a child wrote it.

I'm going to throw out some advise - get beyond C. If you are a C
programmer, then you should be writting operating systems (smile).
I've been programming in Java and C# for a number of years, and being
a high level object oriented languages, the code is much easier to
write and understand.

First you need a thread that just pulls data off the sound card and
puts it into a buffer:

/**
* Audio.java
*
* This program is free softwa you can redistribute it and/or
modify
* it under the terms of the GNU General Public License as published
by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
.

*/
package dopplerradar;

import java.io.*;
import javax.sound.sampled.*;

public final class Audio {

private boolean capture;
ByteArrayOutputStream byteArrayOutputStream;
AudioFormat audioFormat;
TargetDataLine targetDataLine;
Radar parent;
Thread captureThread;
private byte[] captureBuffer;

public Audio(Radar p) {
parent = p;
capture = false;
captureThread = null;
}

public void startCapture() {
try {
stopCapture();

captureBuffer = new byte[2048 * 2]; // 16-bit PCM
audioFormat = setAudioFormat();
capture = true;

DataLine.Info dataLineInfo = new DataLine.Info
(TargetDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getLine
(dataLineInfo);
targetDataLine.open(audioFormat);
targetDataLine.start();

captureThread = new Thread(new AudioCaptureThread());
captureThread.start();
} catch (Exception e) {
System.out.println("captu " + e);
targetDataLine = null;
}
}

public boolean capturing() {
return capture;
}

public void stopCapture() {
capture = false;

if (captureThread != null) {
try {
captureThread.join();
} catch (Exception e) {
}
}

captureThread = null;
}

private AudioFormat setAudioFormat() {
return new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
44100,
16,
1,
2,
44100,
false);
}

class AudioCaptureThread extends Thread {

@Override
public void run() {
byteArrayOutputStream = new ByteArrayOutputStream();

try {
while (capture) {
int cnt = targetDataLine.read(captureBuffer, 0,
captureBuffer.length);

if (cnt 0) {
byteArrayOutputStream.write(captureBuffer, 0,
cnt);
parent.processAudio(byteArrayOutputStream);
}

Thread.sleep(1);
}

byteArrayOutputStream.close();
targetDataLine.close();
} catch (Exception e) {
System.out.println("Error: Audio Thread: " + e);
}
}
}
}

You see the routine inside the thread there called parent.processAudio
(byteArrayOutputStream);

This runs in the background capturing 16 bit PCM sound clips and
joining them together into a stream. When it calls
processAudio it will have more than 44,000 samples per second
(drinking from a hose) which is set by setAudioFormat().


/**
* Radar.java
*
* A Doppler Radar program using a size 2048 FFT
*
* This program is free softwa you can redistribute it and/or
modify
* it under the terms of the GNU General Public License as published
by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
.

*/
package dopplerradar;

import java.io.*;
import javax.swing.*;

public class Radar extends JFrame {

public final Object mutex = new Object();
public GraphicPanel graphicPanel;
public Audio audio;
public FFT fft;
public int yScale = 1;
private double audioLevel;
private double audioFactor;
private byte[] array;
private int arraySize;

public Radar() {
initComponents();

audio = new Audio(this);
arraySize = 2048;
audioLevel = 1024.0D;
audioFactor = 1.0D / audioLevel;

fft = new FFT();
fft.initialize(arraySize);

graphicPanel = new GraphicPanel(this);
jPanel1.add(graphicPanel, java.awt.BorderLayout.CENTER);

audio.startCapture();
}

void setStatus(String s) {
statusLabel.setText(s);
}

public void processAudio(ByteArrayOutputStream stream) {
synchronized (mutex) {
Complex[] in_data = fft.inputArray(); // 2048
Complex values
array = stream.toByteArray(); // 2048 16-bit
PCM values
short v;

int n = 0;
for (int i = 0; i (arraySize * 2); i += 2) {
v = (short) (array[i] & 0xff);
v |= (short) (array[i + 1] 8); // big-
endian ??

in_data[n].setReal(v * audioFactor);
n++;
}

stream.reset();
fft.compute();
}

graphicPanel.displayData(fft.outputArray());
}

etc, etc...

Coupe!