public void playResource(String resourceName) { InputStream in = (getClass().getClassLoader().getResourceAsStream(resourceName)); if (in != null) { try { AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(in)); play(ais); } catch (Exception e) { LOG.error(e); } } else { LOG.debug("[playResource] can't find resource named: {0}", resourceName); } }
protected void playResult(String id) { // Long lid = Long.valueOf(id); if ("-1".equals(id)) { AudioManagerFactory.createAudioManager() .play( getTargetWavURL(), (getTargetMarker().getStart().floatValue() / 1000), (getTargetMarker().getLength().floatValue() / 1000)); } for (RecognitionResult recognitionResult : results) { if (recognitionResult.getInfo().getId().equals(id)) { try { AudioManagerFactory.createAudioManager() .play((new File(recognitionResult.getDetails().getAudioFilePath()).toURI().toURL())); break; } catch (MalformedURLException ex) { log.error(ex); throw new ProcessingException(ex); } } } }
public class SpntAudioListenerHandler implements SpntAudoListener { private static Logger LOG = Logger.getLogger(SpntAudioListenerHandler.class); private SpantusAudioCtx ctx; private SpntAppletEventListener appletEventListener; private Timer levelTimer; public SpntAudioListenerHandler( SpantusAudioCtx ctx, final SpntAppletEventListener anAppletEventListener) { this.ctx = ctx; this.appletEventListener = anAppletEventListener; // javax.swing.timer runs events on swing event thread, so this is safe levelTimer = new Timer( 50, new ActionListener() { public void actionPerformed(ActionEvent e) { appletEventListener.updateMeterChangedValue(); } }); } /** audio device is playing */ public void playingHasStarted() { SwingUtilities.invokeLater( new Runnable() { public void run() { LOG.debug("playingHasStarted"); ctx.setIsPlaying(true); appletEventListener.showStatus("Playing has started"); } }); } /** audio device has finished playing */ public void playingHasEnded() { SwingUtilities.invokeLater( new Runnable() { public void run() { ctx.setIsPlaying(false); LOG.debug("playingHasEnded"); appletEventListener.showStatus("Playing has ended"); } }); } /** Audio device is listening */ public void listeningHasStarted() { SwingUtilities.invokeLater( new Runnable() { public void run() { LOG.debug("listeningHasStarted"); levelTimer.start(); appletEventListener.showStatus("Listening has started"); } }); } /** Audio device has stopped listening */ public void listeningHasEnded() { SwingUtilities.invokeLater( new Runnable() { public void run() { LOG.debug("listeningHasEnded"); ctx.setIsRecording(false); ctx.setIsListening(false); appletEventListener.showStatus("Listening has ended"); levelTimer.stop(); appletEventListener.resetMeterChangedValue(); } }); } }
void playingHasStarted() { LOG.debug("playingHasStarted"); for (SpntAudoListener listener : listeners) { listener.playingHasStarted(); } }
/** * @author cyphers * <p>Controls half-duplex audio, switching between listening, playing, and idle as needed. */ public class AudioDevice implements Runnable { private static Logger LOG = Logger.getLogger(AudioDevice.class); static enum DeviceMode { MODE_IDLE, MODE_PLAY, MODE_RECORD }; DeviceMode mode = DeviceMode.MODE_IDLE; LinkedList<BasicTask> tasks = new LinkedList<BasicTask>(); BasicTask task = null; IdleTask idleTask = new IdleTask(); Thread thread; AudioPlayer audioPlayer = new AudioPlayer(); AudioRecorder audioRecorder = new AudioRecorder(); // Event listeners LinkedList<SpntAudoListener> listeners = new LinkedList<SpntAudoListener>(); /** * Add an event listener * * @param l The listener */ public void addListener(SpntAudoListener l) { listeners.add(l); } /** * Remove an event listener * * @param l The listener */ public void removeListener(SpntAudoListener l) { listeners.remove(l); } void playingHasStarted() { LOG.debug("playingHasStarted"); for (SpntAudoListener listener : listeners) { listener.playingHasStarted(); } } void playingHasEnded() { for (SpntAudoListener listener : listeners) { listener.playingHasEnded(); } } void listeningHasStarted() { for (SpntAudoListener listener : listeners) { listener.listeningHasStarted(); } } void listeningHasEnded() { for (SpntAudoListener listener : listeners) { listener.listeningHasEnded(); } } /** * @author cyphers Ensure that at most one device is active, and that is performing at most one * activity */ abstract class BasicTask implements Runnable { volatile boolean active = false; // Started volatile boolean complete = false; // Finished synchronized void setActive() { active = true; notifyAll(); } synchronized void setComplete() { active = false; complete = true; notifyAll(); } /** Wait for this task to finish */ synchronized void waitComplete() { while (!complete) { try { wait(); } catch (InterruptedException e) { } } } int getFramePosition() { return 0; } abstract void finish(); abstract void abort(); } /** * @author cyphers This task "runs" when there is nothing to do. It just waits for another task to * show up */ class IdleTask extends BasicTask { public void run() { setMode(DeviceMode.MODE_IDLE); synchronized (AudioDevice.this) { while (tasks.isEmpty()) { try { AudioDevice.this.wait(); } catch (InterruptedException e) { } } } } @Override void finish() {} @Override void abort() {} } /** @author cyphers Play some audio */ class PlayTask extends BasicTask { AudioInputStream ais; boolean setStart; boolean last; LineUnavailableException exception; PlayTask(AudioInputStream ais, boolean setStart, boolean last) { this.ais = ais; this.setStart = setStart; this.last = last; } public void run() { setMode(DeviceMode.MODE_PLAY); if (setStart) playingHasStarted(); try { audioPlayer.play(ais, setStart, last); } catch (LineUnavailableException e) { LOG.error(e); exception = e; } if (last) { playingHasEnded(); } } @Override int getFramePosition() { return audioPlayer.getFramePosition(); } @Override synchronized void abort() { if (active) { audioPlayer.stopPlaying(); waitComplete(); } } @Override void finish() { waitComplete(); } } /** @author cyphers Record something */ class RecordTask extends BasicTask { AudioFormat desiredAudioFormat; AudioInputStream ais = null; LineUnavailableException exception = null; volatile boolean ready = false; RecordTask(AudioFormat desiredAudioFormat) { this.desiredAudioFormat = desiredAudioFormat; } public void run() { setMode(DeviceMode.MODE_RECORD); listeningHasStarted(); try { ais = audioRecorder.getAudioInputStream(desiredAudioFormat); } catch (LineUnavailableException e) { exception = e; } synchronized (this) { ready = true; notifyAll(); } waitComplete(); LOG.debug("[RecordTask.run]Waiting for record task is complete"); listeningHasEnded(); LOG.debug("[RecordTask.run]Fired all listening has ended stuff."); } synchronized AudioInputStream getAudioInputStream() throws LineUnavailableException { while (!ready) { try { wait(); } catch (InterruptedException e) { } } if (ais == null) throw exception; else return ais; } @Override void abort() { finish(); } @Override synchronized void finish() { LOG.debug("[RecordTask.finish]FINISH RECORDING: "); if (active) { LOG.debug("[RecordTask.finish]set to idle"); setMode(DeviceMode.MODE_IDLE); setComplete(); } } } public AudioDevice() { thread = new Thread(this); thread.start(); } /** * Play an audio input stream * * @param ais The audio input stream * @param setStart The first frame of this stream is frame 0 for getFramePosition() * @param last If true, playingHasEnded() will be called when the stream finishes playing. */ public void play(AudioInputStream ais, boolean setStart, boolean last) { PlayTask task = new PlayTask(ais, setStart, last); addTask(task); } /** * Play an audio input stream * * @param ais The audio input stream */ public void play(AudioInputStream ais) { play(ais, true, true); } public void playResource(String resourceName) { InputStream in = (getClass().getClassLoader().getResourceAsStream(resourceName)); if (in != null) { try { AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(in)); play(ais); } catch (Exception e) { LOG.error(e); } } else { LOG.debug("[playResource] can't find resource named: {0}", resourceName); } } /** * Wait for audio to become available and return an audio input stream close to the specified * format * * @param format The desired audio format */ public AudioInputStream getAudioInputStream(AudioFormat format) throws LineUnavailableException { RecordTask task = new RecordTask(format); addTask(task); return task.getAudioInputStream(); } synchronized void addTask(BasicTask task) { tasks.add(task); notifyAll(); } public void run() { while (true) { synchronized (this) { task = (tasks.isEmpty()) ? idleTask : (BasicTask) tasks.removeFirst(); task.setActive(); notifyAll(); } task.run(); task.setComplete(); } } /** Finish everything and return */ public void finish() { while (true) { synchronized (this) { task.finish(); if (tasks.isEmpty()) { return; } else { try { wait(); } catch (InterruptedException e) { } } } } } /** Abort everything and return */ public synchronized void abort() { tasks.clear(); task.abort(); notifyAll(); } public int getFramePosition() { synchronized (this) { return task.getFramePosition(); } } public int supportedPlaySampleRate(int desiredSampleRate) throws LineUnavailableException { return audioPlayer.supportedSampleRate(desiredSampleRate); } // Make sure only one direction is going at once void setMode(DeviceMode newMode) { if (mode == newMode) return; switch (mode) { case MODE_PLAY: audioPlayer.closeLine(); break; case MODE_RECORD: audioRecorder.closeLine(); break; } mode = newMode; } /** * Set the preferred target (input) mixer to use. Note, the system may ignore this preference if * the line does not support a suitable format * * @param mInfo Description of mixer */ public void setPreferredTargetMixer(Mixer.Info mInfo) { audioRecorder.setPreferredMixer(mInfo); } /** * Set the preferred target (input) mixer to use. Note, the system may ignore this preference if * the line does not support a suitable format * * @param mInfo Description of mixer */ public void setPreferredTargetMixer(String mInfo) { audioRecorder.setPreferredMixer(mInfo); } public Mixer.Info getPreferredTargetMixer() { return audioRecorder.getPreferredMixer(); } /** * Set the preferred source (output) mixer to use. * * @param mInfo Description of mixer */ public void setPreferredSourceMixer(Mixer.Info mInfo) { audioPlayer.setPreferredMixer(mInfo); } public void setPreferredSourceMixer(String minfo) { audioPlayer.setPreferredMixer(minfo); } public Mixer.Info getPreferredSourceMixer() { return audioPlayer.getPreferredMixer(); } /** * returns a list of target mixers (which also have data lines) * * @return */ public static Mixer.Info[] getAvailableTargetMixers() { return getAvailableMixers(true); } public static Mixer.Info[] getAvailableSourceMixers() { return getAvailableMixers(false); } private static Mixer.Info[] getAvailableMixers(boolean isTarget) { ArrayList<Mixer.Info> mixers = new ArrayList<Mixer.Info>(Arrays.asList((Mixer.Info[]) AudioSystem.getMixerInfo())); for (Iterator<Mixer.Info> it = mixers.iterator(); it.hasNext(); ) { Mixer.Info minfo = it.next(); Mixer mixer = AudioSystem.getMixer(minfo); Line.Info[] linfo = (isTarget) ? mixer.getTargetLineInfo() : mixer.getSourceLineInfo(); boolean hasDataLine = false; for (int j = 0; j < linfo.length; j++) { if (linfo[j] instanceof DataLine.Info) { hasDataLine = true; break; } } if (!hasDataLine) { it.remove(); } } return mixers.toArray(new Mixer.Info[mixers.size()]); } }
/** @author mondhs */ public class RecognizeDetailDialog extends JDialog { private static final String TARGET = "target"; private static final String FEATURE_SCORE = "featureScrore"; private static final String FEATURE = "feature"; private static final String TOTAL_SCORE = "totalScore"; private static final String RECOGNION_RESULT = "recognitionResult"; private static final String SAMPLE_LABEL = "sampleLabel"; private static final String FEATURE_DISTANCE = "featureDistance"; /** */ private static final long serialVersionUID = 1L; private List<RecognitionResult> results; private String selectedSampleId = null; private String selectedFeatureId = null; Logger log = Logger.getLogger(RecognizeDetailDialog.class); private JPanel jContentPane = null; private JPanel mainPanel = null; private JScrollPane resultScrollPane = null; private JEditorPane resultPane; private DtwChartPanel chartPanel = null; private I18n i18n; private URL targetWavURL; private Marker targetMarker; /** @param owner */ public RecognizeDetailDialog(Frame owner, I18n i18n) { super(owner); this.i18n = i18n; initialize(); } /** * This method initializes this * * @return void */ private void initialize() { this.setSize(SwingUtils.currentWindowSize(0.75, 0.75)); SwingUtils.centerWindow(this); setTitle(getI18n().getMessage(RECOGNION_RESULT)); this.setContentPane(getJContentPane()); } @Override protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane thisRootPane = super.createRootPane(); thisRootPane.registerKeyboardAction( new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return thisRootPane; } /** * This method initializes jContentPane * * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(new BorderLayout()); jContentPane.add(getMainPanel(), BorderLayout.CENTER); } return jContentPane; } /** * This method initializes jPanel * * @return javax.swing.JPanel */ private JPanel getMainPanel() { if (mainPanel == null) { mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.add(getResultScrollPane(), BorderLayout.CENTER); mainPanel.add(getChartPanel(), BorderLayout.EAST); } return mainPanel; } /** * This method initializes jScrollPane * * @return javax.swing.JScrollPane */ private JScrollPane getResultScrollPane() { if (resultScrollPane == null) { resultScrollPane = new JScrollPane(); resultScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); resultScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); resultScrollPane.setViewportView(getResultPane()); } return resultScrollPane; } protected DtwChartPanel getChartPanel() { if (chartPanel == null) { chartPanel = new DtwChartPanel(getI18n()); } return chartPanel; } /** * This method initializes jEditorPane * * @return javax.swing.JEditorPane */ protected JEditorPane getResultPane() { if (resultPane == null) { HTMLEditorKit kit = new HTMLEditorKit(); resultPane = new JEditorPane(); resultPane.setEditable(false); resultPane.setContentType("text/html"); resultPane.addHyperlinkListener(new RecognitionHyperlinkListener()); resultPane.setCaretPosition(0); resultPane.setEditorKit(kit); StyleSheet styleSheet = kit.getStyleSheet(); styleSheet.addRule("table{border-width: 1px;}"); styleSheet.addRule("table{border-style: solid;}"); styleSheet.addRule("table{border-color: gray;}"); styleSheet.addRule("table{border-spacing: 0x;}"); styleSheet.addRule("table{width: 100%;}"); styleSheet.addRule("th {border-width: 1px;}"); styleSheet.addRule("th {border-style: solid;}"); styleSheet.addRule("th {border-color: gray;}"); styleSheet.addRule("th {padding: 5px;}"); styleSheet.addRule("td {border-width: 1px;}"); styleSheet.addRule("td.selected {background-color: gray;color: black;}"); styleSheet.addRule("td {border-style: solid;}"); styleSheet.addRule("td {color: gray;}"); styleSheet.addRule("td {padding: 5px;}"); styleSheet.addRule("div {width: 100%;}"); styleSheet.addRule("div {position: absolute;}"); styleSheet.addRule("div {text-align: center;}"); styleSheet.addRule("div {padding: 5px;}"); } return resultPane; } public void updateCtx(List<RecognitionResult> results) { HTMLEditorKit kit = ((HTMLEditorKit) getResultPane().getEditorKit()); // StyleSheet styleSheet = kit.getStyleSheet(); Document doc = kit.createDefaultDocument(); getResultPane().setDocument(doc); getResultPane() .setText("<html><body>" + "<p>" + representResults(results) + "</p></body></html>"); getResultPane().setCaretPosition(0); this.results = results; } private StringBuilder representEmptyResults() { StringBuilder sb = new StringBuilder(); sb.append("<div>") .append("No recognition pattern is found. Try to learn program some patterns first.") .append("</div>"); return sb; } private StringBuilder representResults(List<RecognitionResult> results) { StringBuilder sb = new StringBuilder(); if (results.isEmpty()) { return representEmptyResults(); } String playImgSrc = getClass().getClassLoader().getResource(ImageResourcesEnum.play.getCode()).toString(); sb.append(getI18n().getMessage(TARGET)) .append(html(": <a href=\"play={0,number,#}\">", -1)) .append( html( "<img src=\"{0}\" alt=\"play\" border=\"0\" width=\"24\" height=\"24\" />", playImgSrc)) .append("</a>"); sb.append("<table class=\"resultTable\">"); sb.append("<tr><th>") .append(getI18n().getMessage(SAMPLE_LABEL)) .append("</th><th>") .append(getI18n().getMessage(TOTAL_SCORE)) .append("</th><th>") .append(FEATURE) .append("</th><th>") .append(FEATURE_SCORE) .append("</th><th>") .append(FEATURE_DISTANCE) .append("</th></tr>"); for (RecognitionResult recognitionResult : results) { StringBuilder subTable = new StringBuilder(); int rowsSize = 1; String selectionClass = "notSelected"; if (recognitionResult.getInfo().getId().equals(selectedSampleId)) { selectionClass = "selected"; rowsSize = recognitionResult.getScores().size() + 1; for (Entry<String, Double> scoreEntry : recognitionResult.getScores().entrySet()) { Double distance = recognitionResult.getDetails().getDistances().get(scoreEntry.getKey()); subTable.append("<tr>"); subTable .append(html("<td class=\"{0}\">", selectionClass)) .append(html("<a href=\"show={0}\">", scoreEntry.getKey())) .append(getI18n().getMessage(scoreEntry.getKey())) .append("</a>") .append("</td>") .append(html("<td class=\"{0}\">", selectionClass)) .append(getI18n().getDecimalFormat().format(scoreEntry.getValue())) .append("</td>") .append(html("<td class=\"{0}\">", selectionClass)) .append(getI18n().getDecimalFormat().format(distance)) .append("</td>"); subTable.append("</tr>"); } } sb.append("<tr>"); sb.append(html("<td ROWSPAN=\"{0}\" class=\"{1}\">", rowsSize, selectionClass)); sb.append(html("<a href=\"play={0}\">", recognitionResult.getInfo().getId())) .append( html( "<img src=\"{0}\" alt=\"play\" border=\"0\" width=\"24\" height=\"24\" />", playImgSrc)) .append("</a>") .append(html("<a href=\"show={0}\">", recognitionResult.getInfo().getId())); if (recognitionResult.getInfo().getId().equals(selectedSampleId)) { // collapsed + sb.append("⊟"); } else { // expanded - sb.append("⊞"); } sb.append(recognitionResult.getInfo().getName()).append("</a>"); // show expanded id if (recognitionResult.getInfo().getId().equals(selectedSampleId)) { sb.append("<span>[id=").append(recognitionResult.getInfo().getId()).append("]</span>"); } sb.append("</td>"); sb.append(html("<td ROWSPAN=\"{0}\" class=\"{1}\">", rowsSize, selectionClass)) .append(getI18n().getDecimalFormat().format(recognitionResult.getDistance())) .append("</td>"); // how features are generated if (rowsSize == 1) { sb.append(html("<td class=\"{0}\">", selectionClass)).append("</td>"); sb.append(html("<td class=\"{0}\">", selectionClass)).append("</td>"); sb.append(html("<td class=\"{0}\">", selectionClass)).append("</td>"); } sb.append("</tr>"); sb.append(subTable); } sb.append("</table>"); return sb; } protected String html(String patter, Object... args) { return MessageFormat.format(patter, args); } @Override public void dispose() { super.dispose(); selectedFeatureId = null; selectedSampleId = null; results = null; } public I18n getI18n() { return i18n; } public void setI18n(I18n i18n) { this.i18n = i18n; } public Marker getTargetMarker() { return targetMarker; } public void setTargetMarker(Marker targetMarker) { this.targetMarker = targetMarker; } public URL getTargetWavURL() { return targetWavURL; } public void setTargetWavURL(URL targetWavURL) { this.targetWavURL = targetWavURL; } protected void showResult(String id) { // check if number that mean sample id if (Pattern.matches("^\\d*$", id)) { // Long key = Long.valueOf(id); if (id.equals(selectedSampleId)) { selectedSampleId = null; } else { selectedSampleId = id; } selectedFeatureId = null; } else { // if this not a number lets say is feature id selectedFeatureId = id; } updateCtx(results); if (selectedSampleId == null) { getChartPanel().setRecognitionResult(null); getChartPanel().repaintCharts(null, null); return; } for (RecognitionResult recognitionResult : results) { if (recognitionResult.getInfo().getId().equals(selectedSampleId)) { getChartPanel().repaintCharts(recognitionResult, selectedFeatureId); // List<Point> points = // recognitionResultDetails.getPath().get(selctedFeatureId); // if (points != null) { // //if some feature selected paint only this feature // getChartPanel().setRecognitionResult(recognitionResultDetails, // selctedFeatureId); // } else { // //if none feature is selected paint all features // getChartPanel().setRecognitionResult(recognitionResultDetails); // } break; } } getChartPanel().repaint(); } protected void playResult(String id) { // Long lid = Long.valueOf(id); if ("-1".equals(id)) { AudioManagerFactory.createAudioManager() .play( getTargetWavURL(), (getTargetMarker().getStart().floatValue() / 1000), (getTargetMarker().getLength().floatValue() / 1000)); } for (RecognitionResult recognitionResult : results) { if (recognitionResult.getInfo().getId().equals(id)) { try { AudioManagerFactory.createAudioManager() .play((new File(recognitionResult.getDetails().getAudioFilePath()).toURI().toURL())); break; } catch (MalformedURLException ex) { log.error(ex); throw new ProcessingException(ex); } } } } class RecognitionHyperlinkListener implements HyperlinkListener { /** @param e */ public void hyperlinkUpdate(HyperlinkEvent e) { if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) { StringTokenizer st = new StringTokenizer(e.getDescription(), " "); if (st.hasMoreTokens()) { String selectedID = st.nextToken(); if (selectedID.startsWith("play=")) { selectedID = selectedID.replace("play=", ""); playResult(selectedID); } else if (selectedID.startsWith("show=")) { selectedID = selectedID.replace("show=", ""); showResult(selectedID); } } } } } public String getSelectedSampleId() { return selectedSampleId; } public void setSelectedSampleId(String selectedSampleId) { this.selectedSampleId = selectedSampleId; } }