Monday, April 28, 2008

Use Scope definition instead of rule parameters in ANTLR3

In the SimpleC to LLVM translation project, I need to pass a parameter as a flag variable into a parser rule.  However, if I add a parameter to the rule declaration, I have to change all the references to that rule into rule[args].

As an alternative solution, I use Scope definition and put that flag variable in to the declared scope.  Whenever I need that flag variable, I can import that global scope within the parser rule to get reference to that variable.  

In this case:
grammar G;
assignment
scope {boolean isLeftHandSide;}
    :  {$assignment::isLeftHandSide=true;}ID '=' 
       {$assignment::isLeftHandSide=false;}ID
    ;
...
expression 
    :  ID {if($assignment::isLeftHandSide) doSomething();}
    ;

Reference: The Definitive ANTLR Reference, chapter 4.5

Friday, April 25, 2008

Java sound

After switched to MAC, I can't find a bemani emulator for MacOS. I want to write one myself.
I'm trying to make Java play wave audio. Found a sample code online. But the sound doesn't play in run mode. It only plays in debug mode. I found the Clip.drain() method can block the program till the audio data in I/O is empty/played.

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

public class EntryPoint {
public void playSound() {
try {
// From file
AudioInputStream stream = AudioSystem.getAudioInputStream(new File("/Users/shaotingcai/Documents/USF/cs652/JavaSound/src/me.wav"));

// From URL
//stream = AudioSystem.getAudioInputStream(new URL("http://hostname/audiofile"));

// At present, ALAW and ULAW encodings must be converted
// to PCM_SIGNED before it can be played
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
format = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits()*2,
format.getChannels(),
format.getFrameSize()*2,
format.getFrameRate(),
true); // big endian
stream = AudioSystem.getAudioInputStream(format, stream);
}

// Create the clip
DataLine.Info info = new DataLine.Info(
Clip.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()));
Clip clip = (Clip) AudioSystem.getLine(info);

// This method does not return until the audio file is completely loaded
clip.open(stream);
System.out.println("opened.");

// Start playing
clip.start();
clip.drain();
System.out.println("played");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
EntryPoint main = new EntryPoint();
main.playSound();
}
}