Compare commits

..

No commits in common. "master" and "v0.1" have entirely different histories.
master ... v0.1

4 changed files with 81 additions and 197 deletions

View File

@ -5,8 +5,8 @@ FreqSample is a tool made in Java that will play a frequency.
### Compiling ### Compiling
Make sure you have the JDK installed along with Apache Ant. Then go to the root directory of this project and run: Make sure you have the JDK installed along with Apache Ant. Then go to the root directory of this project and run:
```bash ```
$ ant $ ant jar
``` ```
### Contributing ### Contributing

View File

@ -11,7 +11,7 @@
<target name="compile" > <target name="compile" >
<mkdir dir="${classes.dir}" /> <mkdir dir="${classes.dir}" />
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}" /> <javac srcdir="${src.dir}" destdir="${classes.dir}" />
</target> </target>
<target name="jar" depends="compile" > <target name="jar" depends="compile" >
@ -22,10 +22,4 @@
</manifest> </manifest>
</jar> </jar>
</target> </target>
<target name="main" depends="jar" />
<target name="run" depends="jar" >
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true" />
</target>
</project> </project>

View File

@ -1,141 +1,101 @@
package freqsample; package freqsample;
import java.awt.event.*; import java.nio.ByteBuffer;
import javax.swing.*;
import javax.sound.sampled.*; import javax.sound.sampled.*;
import javax.swing.*;
/** /**
* @author Nicolás A. Ortega * @author Nicolás A. Ortega
* @copyright Nicolás A. Ortega * @copyright Nicolás A. Ortega
* @license GNU GPLv3 * @license GPLv3
* @year 2014 * @year 2014
* *
*/ */
public class FreqSample { public class FreqSample {
private static final String version = "v1.1.1"; private static final String version = "v0.1";
private JFrame frame;
private JPanel panel;
private JTextField hzField, msField;
private JLabel hzLabel, msLabel;
private JButton playButton;
private JMenuBar menuBar; public FreqSample(double hz, double msecs) throws InterruptedException, LineUnavailableException {
private JMenu fsMenu, helpMenu; final int SAMPLE_RATE = 44100;
private JMenuItem quitItem, copyrightItem, aboutItem; final int SAMPLE_SIZE = 2;
public FreqSample() { SourceDataLine line;
frame = new JFrame("FreqSample"); double fFreq = hz;
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel(); double fCyclePosition = 0;
frame.add(panel);
setupMenu(); AudioFormat af = new AudioFormat(SAMPLE_RATE, 16, 1, true, true);
setupUI(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
frame.setVisible(true); if(!AudioSystem.isLineSupported(info)) {
System.out.println("Line matching " + info + " is not supported.");
throw new LineUnavailableException();
} }
private void setupMenu() { line = (SourceDataLine)AudioSystem.getLine(info);
menuBar = new JMenuBar(); line.open(af);
fsMenu = new JMenu("FreqSample"); line.start();
helpMenu = new JMenu("Help");
quitItem = new JMenuItem("Quit"); ByteBuffer cBuf = ByteBuffer.allocate(line.getBufferSize());
quitItem.addActionListener(new ActionListener() {
@Override int ctSamplesTotal = SAMPLE_RATE * (int)(msecs / 1000);
public void actionPerformed(ActionEvent ae) {
System.exit(0); while(ctSamplesTotal > 0) {
double fCycleInc = fFreq/SAMPLE_RATE;
cBuf.clear();
int ctSamplesThisPass = line.available() / SAMPLE_SIZE;
for(int i = 0; i < ctSamplesThisPass; i++) {
cBuf.putShort((short)(Short.MAX_VALUE * Math.sin(2 * Math.PI * fCyclePosition)));
fCyclePosition += fCycleInc;
if(fCyclePosition > 1) fCyclePosition -= 1;
} }
}); line.write(cBuf.array(), 0, cBuf.position());
quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK)); ctSamplesTotal -= ctSamplesThisPass;
fsMenu.add(quitItem);
copyrightItem = new JMenuItem("Copyright Info"); while(line.getBufferSize() / 2 < line.available()) {
copyrightItem.addActionListener(new ActionListener() { Thread.sleep(1);
@Override }
public void actionPerformed(ActionEvent ae) { }
new Window("Copyright Information",
"FreqSample " + version + ", play frequencies.\n" + line.drain();
"Copyright (C) 2014 Nicolás A. Ortega\n\n" + line.close();
}
public static void main(String[] args) throws InterruptedException, LineUnavailableException {
if(args.length <= 2 && args.length != 0) {
if(args.length == 1) {
if(args[0].equals("-h")) printHelp();
else if(args[0].equals("-c")) printCopyright();
else if(args[0].equals("-v")) System.out.println(version);
else printHelp();
} else {
double hz = Double.parseDouble(args[0]);
double ms = Double.parseDouble(args[1]);
new FreqSample(hz, ms);
}
} else {
printHelp();
}
}
private static void printHelp() {
System.out.println("Usage: java -jar FreqSample.jar [option][<hz> <ms>]");
System.out.println(" -h -- Print this help information");
System.out.println(" -c -- Print copyright information");
System.out.println(" -v -- Print version\n");
}
private static void printCopyright() {
System.out.println("FreqSample, a simple frequency sampler.\n" +
"Copyright (C) 2014 Nicolás A. Ortega\n" +
"This program is free software: you can redistribute it and/or modify\n" + "This program is free software: you can redistribute it and/or modify\n" +
"it under the terms of the GNU General Public License as published by\n" + "it under the terms of the GNU General Public License as published by\n" +
"the Free Software Foundation, either version 3 of the License, or\n" + "the Free Software Foundation, either version 3 of the License, or\n" +
"(at your option) any later version.\n" + "(at your option) any later version.\n\n" +
"This program is distributed in the hope that it will be useful,\n" + "This program is distributed in the hope that it will be useful,\n" +
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
"GNU General Public License for more details.\n\n" + "GNU General Public License for more details.");
"You should have received a copy of the GNU General Public License\n" +
"along with this program. If not, see <http://www.gnu.org/licenses/>.\n\n");
}
});
helpMenu.add(copyrightItem);
aboutItem = new JMenuItem("About");
aboutItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
new Window("About",
"FreqSample " + version + "\n" +
"Copyright (C) 2014 Nicolás A. Ortega\n" +
"License: GNU GPLv3\n" +
"Contact: nicolas.ortega.froysa@gmail.com\n" +
"Source-Code: https://github.com/Deathsbreed/FreqSample\n" +
"Developers: Nicolás Ortega\n\n");
}
});
helpMenu.add(aboutItem);
menuBar.add(fsMenu);
menuBar.add(helpMenu);
frame.setJMenuBar(menuBar);
}
private void setupUI() {
panel.setLayout(null);
hzLabel = new JLabel("Frequency (Hz):");
hzLabel.setBounds(10, 10, 150, 25);
panel.add(hzLabel);
hzField = new JTextField();
hzField.setBounds(170, 10, 220, 25);
panel.add(hzField);
msLabel = new JLabel("Duration (ms):");
msLabel.setBounds(10, 40, 150, 25);
panel.add(msLabel);
msField = new JTextField();
msField.setBounds(170, 40, 220, 25);
panel.add(msField);
playButton = new JButton("Play");
playButton.setBounds(160, 80, 80, 25);
playButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
double hz = Double.parseDouble(hzField.getText());
double ms = Double.parseDouble(msField.getText());
try {
Generator.generateTone(hz, ms);
} catch(InterruptedException ie) {
ie.printStackTrace();
System.exit(1);
} catch(LineUnavailableException lue) {
lue.printStackTrace();
System.exit(1);
} }
} }
});
panel.add(playButton);
}
public class Window {
public Window(String title, String msg) {
JOptionPane.showMessageDialog(null, msg, title, JOptionPane.INFORMATION_MESSAGE);
}
}
public static void main(String[] args) { new FreqSample(); }
}

View File

@ -1,70 +0,0 @@
package freqsample;
import java.nio.ByteBuffer;
import javax.sound.sampled.*;
import javax.swing.*;
/**
* @author Nicolás A. Ortega
* @copyright Nicolás A. Ortega
* @license GNU GPLv3
* @year 2014
*
*/
public class Generator {
public static void generateTone(double hz, double msecs) throws InterruptedException, LineUnavailableException {
final int SAMPLE_RATE = 44100;
final int SAMPLE_SIZE = 2;
SourceDataLine line;
double fFreq = hz;
double fCyclePosition = 0;
// Open Audio Device
AudioFormat af = new AudioFormat(SAMPLE_RATE, 16, 1, true, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
if(!AudioSystem.isLineSupported(info)) {
System.out.println("Line matching " + info + " is not supported.");
throw new LineUnavailableException();
}
line = (SourceDataLine)AudioSystem.getLine(info);
line.open(af);
line.start();
// The audio bytebuffer
ByteBuffer cBuf = ByteBuffer.allocate(line.getBufferSize());
// Set the total samples to loop through
if(msecs < 150) msecs = 150;
int ctSamplesTotal = (int)(SAMPLE_RATE * (msecs / 1000));
while(ctSamplesTotal > 0) {
// Define the frequency at the given sample rate
double fCycleInc = fFreq/SAMPLE_RATE;
// Clear the buffer
cBuf.clear();
// Play the frequency
int ctSamplesThisPass = line.available() / SAMPLE_SIZE;
for(int i = 0; i < ctSamplesThisPass; i++) {
cBuf.putShort((short)(Short.MAX_VALUE * Math.sin(2 * Math.PI * fCyclePosition)));
fCyclePosition += fCycleInc;
if(fCyclePosition > 1) fCyclePosition -= 1;
}
line.write(cBuf.array(), 0, cBuf.position());
ctSamplesTotal -= ctSamplesThisPass;
while(line.getBufferSize() / 2 < line.available()) {
Thread.sleep(1);
}
}
// Close the audioline
line.drain();
line.close();
}
}