View Single Post
Old 11-08-2010, 11:33 AM   #4 (permalink)
dcb
needs more cowbell
 
dcb's Avatar
 
Join Date: Feb 2008
Location: ÿ
Posts: 5,038

pimp mobile - '81 suzuki gs 250 t
90 day: 96.29 mpg (US)

schnitzel - '01 Volkswagen Golf TDI
90 day: 53.56 mpg (US)
Thanks: 158
Thanked 269 Times in 212 Posts
Mpg.java

you can try the java soundcard mpg thingie, does the ppc have stereo inputs?
Code:
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.NumberFormat;
import java.util.Properties;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Mpg extends Thread {
	static String propFile = "./mpg.properties";	// place to persist confguration and trips. 
												//Will be created on first run if it doesnt exist.

	static int injThreshold = Integer
			.parseInt(getProperty("injThreshold", "-30")); // value above the noise

	static int vssThreshold = Integer
			.parseInt(getProperty("vssThreshold", "100")); // value above the noise

	static double distanceFudge = Double.parseDouble(getProperty("distanceFudge", "3200.0"));

	static double fuelFudge = Double.parseDouble(getProperty("fuelFudge",	"8000000.00"));

	static String dummyFile = getProperty("dummyFile", "");

	// low level stats tracked in the "trip" class.
	class Trip {
		String name;

		long sampleCount; // num samples, used to compute elapsed time, good
							// for about 58 billion hours @ 44100hz

		long injHi; // stores number of samples that were "HI" (injector was
					// open)

		long vssTot; // how many pulses from the vss, indication of distance
						// travelled

		public Trip(String _name) {
			name = _name;
		}

		// real lightweight update process, gets called at end of audio chunk
		public void Update(long _sampleCount, long _injHi, long _vssTot) {
			sampleCount += _sampleCount;
			injHi += _injHi;
			vssTot += _vssTot;
		}

		public String toString() {
			return "name=" + name + ";sampleCount=" + sampleCount + ";injHi="
					+ injHi + ";vssTot=" + vssTot;
		}

		public void reset() {
			sampleCount = 0;
			injHi = 0;
			vssTot = 0;
		}

		public Trip load() {
			sampleCount = Long
					.parseLong(getProperty(name + ".sampleCount", "0"));
			injHi = Long.parseLong(getProperty(name + ".injHi", "0"));
			vssTot = Long.parseLong(getProperty(name + ".vssTot", "0"));
			return this;
		}

		public void save() {
			properties.put(name + ".sampleCount", "" + sampleCount);
			properties.put(name + ".injHi", "" + injHi);
			properties.put(name + ".vssTot", "" + vssTot);
		}

		public double miles() {
			return (double) vssTot / distanceFudge;
		}

		public double hours() {
			return ((double) sampleCount) / (44100.0D * 3600.0D);
		}

		public double gallons() {
			return (double) injHi / fuelFudge;
		}

		public double mpg() {
			return gallons() > 0.0D ? (miles() / gallons())
					: Double.POSITIVE_INFINITY;
		}
	}

	class TripPanel extends JPanel {
		Trip trip = null;

		JLabel name = new JLabel("name");

		JLabel miles = new JLabel("miles");

		JLabel gallons = new JLabel("gallons");

		JLabel mpg = new JLabel("mpg");

		JLabel hours = new JLabel("gallons");

		JLabel mph = new JLabel("mph");

		JButton reset = new JButton("reset");

		/** used for limiting numbers to 4 decimal places*/
		NumberFormat fm = NumberFormat.getNumberInstance();

		public TripPanel(Trip _trip) {
			trip = _trip;
			setLayout(new GridLayout(1, 8));
			setBorder(BorderFactory.createLineBorder(Color.BLACK));
			add(name);
			add(miles);
			add(gallons);
			add(mpg);
			add(hours);
			add(mph);
			add(reset);
			reset.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					trip.reset();
				}
			});
			fm.setMaximumFractionDigits(4);
		}

		public void upDateLabels() {
			name.setText(" " + trip.name);
			miles.setText(fm.format(trip.miles()));
			gallons.setText(fm.format(trip.gallons()));
			mpg.setText(fm.format(trip.mpg()));
			hours.setText(fm.format(trip.hours()));
			mph.setText(fm.format(trip.miles() / trip.hours()));
		}

	}

	private TargetDataLine m_line;

	protected boolean m_bRecording = true;

	Trip instant = new Trip("instant");

	TripPanel instantPanel = new TripPanel(instant);

	Trip current = new Trip("current");

	TripPanel currentPanel = new TripPanel(current);

	Trip tank = new Trip("tank").load();

	TripPanel tankPanel = new TripPanel(tank);

	public Mpg(TargetDataLine line, AudioFileFormat.Type targetType) {
		m_line = line;

		new Thread(new Runnable() {// thread to update the view every second
					public void run() {
						while (m_bRecording) {
							instantPanel.upDateLabels();
							instant.reset();// reset the instant trip after
											// displaying it
							currentPanel.upDateLabels();
							tankPanel.upDateLabels();
							try {
								Thread.sleep(1000);
							} catch (Exception e) {
							}
						}
					}
				}).start();

	}

	public void start() {
		m_line.start();
		super.start();
	}

	public void stopRecording() {
		m_line.stop();
		m_line.close();
		m_bRecording = false;
		System.out.println(" inj sampleCount = " + current.sampleCount
				+ " inj hi = " + current.injHi + " inj vssTot = "
				+ current.vssTot);
	}

	boolean ig = true;

	boolean vg = true;

	void processChunk(byte[] b, int c) {
		long ih = 0;
		long vt = 0;

		for (int x = 0; x < c; x += 2) {
			int val = ((int) b[x] & 255) - 127;
			if (val > vssThreshold && vg) {
				vt++;
				System.out.println(" vss going hi "
						+ (current.sampleCount + (x / 2)));
				vg = false;
			}
			if (val < 0) {
				vg = true;
			}

			val = ((int) b[x + 1] & 255) - 127;
			if (val < injThreshold) {
				ig = true;
			}
			if (val > 0)
				ig = false;
			if (ig)
				ih++;
		}
		instant.Update(c / 2, ih, vt);
		current.Update(c / 2, ih, vt);
		tank.Update(c / 2, ih, vt);
	}

	public void realrun() {
		byte[] buffer = new byte[m_line.getBufferSize()];
		while (m_bRecording) {
			int c = m_line.read(buffer, 0, m_line.available());
			if (c != 0) {
				processChunk(buffer, c);
			}
		}
	}

	public void run() {
		if ("".equals(dummyFile))
			realrun();
		else
			dummyrun();
	}

	public void dummyrun() {
		try {
			String strFilename = dummyFile;
			File soundFile = new File(strFilename);
			AudioInputStream audioInputStream = null;
			audioInputStream = AudioSystem.getAudioInputStream(soundFile);

			int nBytesRead = 0;
			byte[] abData = new byte[44100];
			while (nBytesRead != -1) {
				nBytesRead = audioInputStream.read(abData, 0, abData.length);
				if (nBytesRead >= 0) {
					processChunk(abData, nBytesRead);
				}
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {

		AudioFormat audioFormat = new AudioFormat(
				AudioFormat.Encoding.PCM_SIGNED, 44100.0F, 8, 2, 2, 44100.0F,
				false);
		DataLine.Info info = new DataLine.Info(TargetDataLine.class,
				audioFormat);
		TargetDataLine targetDataLine = null;
		targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
		targetDataLine.open(audioFormat);
		AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE;

		final Mpg recorder = new Mpg(targetDataLine, targetType);
		JFrame j = new JFrame("MPG Monitor!!!");
		j.setSize(640, 125);
		Container c = j.getContentPane();
		c.setLayout(new GridLayout(4, 1));

		JPanel hd = new JPanel();
		hd.setLayout(new GridLayout(1, 8));
		hd.add(new JLabel(""));
		hd.add(new JLabel("MILES"));
		hd.add(new JLabel("GAL"));
		hd.add(new JLabel("MPG"));
		hd.add(new JLabel("HRS"));
		hd.add(new JLabel("MPH"));
		hd.add(new JLabel(""));

		c.add(hd);
		c.add(recorder.instantPanel);
		c.add(recorder.currentPanel);
		c.add(recorder.tankPanel);

		j.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				recorder.stopRecording();
				recorder.tank.save();//this just adds the trip fields to the properties object
				try {
					properties.store(new FileOutputStream(new File(propFile)),"");
				} catch (Exception f) {
				}
				System.exit(0);
			}
		});

		j.setVisible(true);
		recorder.start();

	}

	static Properties properties;

	static String getProperty(String tag, String dflt) {
		String s = "";

		try {
			if (properties == null) {
				properties = new Properties();
				try {
					properties.load(new FileInputStream(new File(propFile)));
				} catch (Exception e) {
				}
				;
			}
			s = properties.getProperty(tag);
			if (s == null) {
				s = dflt;
				properties.put(tag, s);// will propogate default values to the
										// file
			}
		} catch (Exception e) {
		}
		return s;

	}

}
__________________
WINDMILLS DO NOT WORK THAT WAY!!!
  Reply With Quote