Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

249
LINES

< > BotCompany Repo | #1009283 // Echo! [WORKS]

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Uses 59K of libraries. Click here for Pure Java version (661L/6K/15K).

!7

// AudioLoop from jsresources.org

import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.AudioFileFormat;

import gnu.getopt.Getopt; lib 1009286 // getopt

static boolean	DEBUG;
static final int	DEFAULT_INTERNAL_BUFSIZ = 40960;
static final int	DEFAULT_EXTERNAL_BUFSIZ = 40960;


p {
	String	strMixerName = null;
	float	fFrameRate = 44100.0F;
	int	nInternalBufferSize = DEFAULT_INTERNAL_BUFSIZ;
	int	nExternalBufferSize = DEFAULT_EXTERNAL_BUFSIZ;

	Getopt	g = new Getopt("AudioLoop", args, "hlr:i:e:M:D");
	int	c;
	while ((c = g.getopt()) != -1)
	{
		switch (c)
		{
		case 'h':
			printUsage();
			ret;

		case 'l':
			javaSound_listMixers();
			ret;

		case 'r':
			fFrameRate = Float.parseFloat(g.getOptarg());
			if (DEBUG) { out("AudioLoop.main(): frame rate: " + fFrameRate); }
			break;

		case 'i':
			nInternalBufferSize = Integer.parseInt(g.getOptarg());
			if (DEBUG) { out("AudioLoop.main(): internal buffer size: " + nInternalBufferSize); }
			break;

		case 'e':
			nExternalBufferSize = Integer.parseInt(g.getOptarg());
			if (DEBUG) { out("AudioLoop.main(): external buffer size: " + nExternalBufferSize); }
			break;

		case 'M':
			strMixerName = g.getOptarg();
			if (DEBUG) { out("AudioLoop.main(): mixer name: " + strMixerName); }
			break;

		case 'D':
			DEBUG = true;
			break;

		case '?':
			printUsage();
			ret;

		default:
			out("AudioLoop.main(): getopt() returned: " + c);
			break;
		}				
	}
	AudioFormat	audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, fFrameRate, 16, 2, 4, fFrameRate, false);
	if (DEBUG) { out("AudioLoop.main(): audio format: " + audioFormat); }
	AudioLoop	audioLoop = null;
	try
	{
		audioLoop = new AudioLoop(audioFormat,
					  nInternalBufferSize,
					  nExternalBufferSize,
					  strMixerName);
	}
	catch (LineUnavailableException e)
	{
		e.printStackTrace();
		System.exit(1);
	}
	audioLoop.start();
}


// TODO: params for audio quality, optionally use compression and decompression in the loop (see ~/AudioLoop.java)

/**	<titleabbrev>AudioLoop</titleabbrev>
	<title>Recording and playing back the recorded data immediately</title>

	<formalpara><title>Purpose</title>
	<para>
	This program opens two lines: one for recording and one
	for playback. In an infinite loop, it reads data from
	the recording line and writes them to the playback line.
	You can use this to measure the delays inside Java Sound:
	Speak into the microphone and wait untill you hear
	yourself in the speakers.  This can be used to
	experience the effect of changing the buffer sizes: use
	the <option>-e</option> and <option>-i</option> options.
	You will notice that the
	delays change, too.
	</para></formalpara>

	<formalpara><title>Usage</title>
	<para>
	<cmdsynopsis>
	<command>java AudioLoop</command>
	<arg choice="plain"><option>-l</option></arg>
	</cmdsynopsis>
	<cmdsynopsis>
	<command>java AudioLoop</command>
	<arg><option>-M <replaceable>mixername</replaceable></option></arg>
	<arg><option>-e <replaceable>buffersize</replaceable></option></arg>
	<arg><option>-i <replaceable>buffersize</replaceable></option></arg>
	</cmdsynopsis>
	</para></formalpara>

	<formalpara><title>Parameters</title>
	<variablelist>
	<varlistentry>
	<term><option>-l</option></term>
	<listitem><para>lists the available mixers</para></listitem>
	</varlistentry>
	<varlistentry>
	<term><option>-M <replaceable>mixername</replaceable></option></term>
	<listitem><para>selects a mixer to play on</para></listitem>
	</varlistentry>
	<varlistentry>
	<term><option>-e <replaceable>buffersize</replaceable></option></term>
	<listitem><para>the buffer size to use in the application ("extern")</para></listitem>
	</varlistentry>
	<varlistentry>
	<term><option>-i <replaceable>buffersize</replaceable></option></term>
	<listitem><para>the buffer size to use in Java Sound ("intern")</para></listitem>
	</varlistentry>
	</variablelist>
	</formalpara>

	<formalpara><title>Bugs, limitations</title>
	<para>
	There is no way to stop the program besides brute force
	(ctrl-C). There is no way to set the audio quality.
	</para>

	<para>The example requires that the soundcard and its driver
	as well as the Java Sound implementation support full-duplex
	operation. In Linux either use <ulink
	url="http://www.tritonus.org/">Tritonus</ulink> or enable
	full-duplex in Sun's Java Sound implementation (search the
	archive of java-linux).</para>
	</formalpara>

	<formalpara><title>Source code</title>
	<para>
	<ulink url="AudioLoop.java.html">AudioLoop.java</ulink>,
	<ulink url="AudioCommon.java.html">AudioCommon.java</ulink>,
	<ulink url="http://www.urbanophile.com/arenn/hacking/download.html">gnu.getopt.Getopt</ulink>
	</para>
	</formalpara>
*/
sclass AudioLoop extends Thread {
	private TargetDataLine	m_targetLine;
	private SourceDataLine	m_sourceLine;
	private boolean		m_bRecording;
	private int		m_nExternalBufferSize;


	/*
	 *	We have to pass an AudioFormat to describe in which
	 *	format the audio data should be recorded and played.
	 */
	public AudioLoop(AudioFormat format,
			 int nInternalBufferSize,
			 int nExternalBufferSize,
			 String strMixerName)
		throws	LineUnavailableException
	{
		Mixer		mixer = null;
		if (strMixerName != null)
		{
			Mixer.Info	mixerInfo = javaSound_getMixerInfo(strMixerName);
			if (DEBUG) { out("AudioLoop.<init>(): mixer info: " + mixerInfo); }
			mixer = AudioSystem.getMixer(mixerInfo);
			if (DEBUG) { out("AudioLoop.<init>(): mixer: " + mixer); }
		}
		/*
		 *	We retrieve and open the recording and the playback line.
		 */
		DataLine.Info	targetInfo = new DataLine.Info(TargetDataLine.class, format, nInternalBufferSize);
		DataLine.Info	sourceInfo = new DataLine.Info(SourceDataLine.class, format, nInternalBufferSize);
		if (mixer != null)
		{
			m_targetLine = (TargetDataLine) mixer.getLine(targetInfo);
			m_sourceLine = (SourceDataLine) mixer.getLine(sourceInfo);
		}
		else
		{
			m_targetLine = (TargetDataLine) AudioSystem.getLine(targetInfo);
			m_sourceLine = (SourceDataLine) AudioSystem.getLine(sourceInfo);
		}
		if (DEBUG) { out("AudioLoop.<init>(): SourceDataLine: " + m_sourceLine); }
		if (DEBUG) { out("AudioLoop.<init>(): TargetDataLine: " + m_targetLine); }
		m_targetLine.open(format, nInternalBufferSize);
		m_sourceLine.open(format, nInternalBufferSize);
		m_nExternalBufferSize = nExternalBufferSize;
		}

	public void start() {
		m_targetLine.start();
		m_sourceLine.start();
		super.start();
	}

	public void run() {
		byte[]	abBuffer = new byte[m_nExternalBufferSize];
		int	nBufferSize = abBuffer.length;
		m_bRecording = true;
		while (m_bRecording) {
			if (DEBUG) { out("Trying to read: " + nBufferSize); }
			/*
			 *	read a block of data from the recording line.
			 */
			int	nBytesRead = m_targetLine.read(abBuffer, 0, nBufferSize);
			if (DEBUG) { out("Read: " + nBytesRead); }
			/*
			 *	And now, we write the block to the playback
			 *	line.
			 */
			m_sourceLine.write(abBuffer, 0, nBytesRead);
		}
	}
}

svoid out(S s) { print(s); }

static void printUsage() {
	out("AudioLoop: usage:");
	out("\tjava AudioLoop -h");
	out("\tjava AudioLoop -l");
	out("\tjava AudioLoop [-D] [-M <mixername>] [-e <buffersize>] [-i <buffersize>]");
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, wtqryiryparv

No comments. add comment

Snippet ID: #1009283
Snippet name: Echo! [WORKS]
Eternal ID of this version: #1009283/10
Text MD5: 6ad6865d8594e4cc800646974e5e6a5e
Transpilation MD5: c134b729202e6fe00cd4a22744a0ec31
Author: stefan
Category: javax / sound
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-07-21 01:37:51
Source code size: 7684 bytes / 249 lines
Pitched / IR pitched: No / No
Views / Downloads: 434 / 559
Version history: 9 change(s)
Referenced in: #1009287 - Echo! [shortened]