001    /*
002     * Copyright (C) 2006-2010 Enrique Lara (k957@68k.org)
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006      * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package net.sf.jmorse;
018    
019    import net.sf.jmorse.util.logging.Logger;
020    
021    import java.util.Locale;
022    
023    import javax.sound.sampled.AudioFormat;
024    import javax.sound.sampled.AudioInputStream;
025    import javax.sound.sampled.AudioSystem;
026    import javax.sound.sampled.DataLine;
027    import javax.sound.sampled.SourceDataLine;
028    
029    /**
030     * @author <a href="mailto:k957@68k.org">Enrique Lara</a>
031     */
032    public class AudioMorseWriter extends AbstractMorseWriter {
033        private static final Logger s_log = Logger.getLogger(AudioMorseWriter.class);
034        private static final boolean DEBUG_ENABLED = s_log.isDebugEnabled();
035    
036        public AudioMorseWriter() {
037            super();
038        }
039    
040        public AudioMorseWriter(Locale locale) {
041            super(locale);
042        }
043    
044        public AudioMorseWriter(int wpm, int tone, int volume) {
045            super();
046            setWpm(wpm);
047            setTone(tone);
048            setVolume(volume);
049        }
050    
051        protected int volume = MorseUtil.DEFAULT_VOLUME;
052        protected int tone = MorseUtil.DEFAULT_TONE;
053    
054        // --------------------------------------------------- Properties
055        public int getVolume() {
056            return this.volume;
057        }
058    
059        public int getTone() {
060            return this.tone;
061        }
062    
063        public void setVolume(int volume) {
064            this.volume = volume;
065    
066            if (this.volume > 10) {
067                this.volume = 11;
068            }
069    
070            if (this.volume < 0) {
071                this.volume = 0;
072            }
073        }
074    
075        public void setTone(int tone) {
076            this.tone = tone;
077        }
078    
079        protected void writeMorse(char[] msg, int len) {
080            short v = (short) (12.7 * volume);
081    
082            if (DEBUG_ENABLED) {
083                s_log.debug("tone=" + tone);
084                s_log.debug("volume=" + volume);
085            }
086    
087            if (DEBUG_ENABLED) {
088                s_log.debug("play msg:" + new String(msg, 0, len));
089            }
090    
091            MorseBeep mb = new MorseBeep();
092            mb.setVolume(v);
093            mb.setTone(tone);
094            mb.setWpm((short) wpm);
095    
096            byte[] audioData = mb.generateAudioData(msg, len);
097            boolean result = (audioData != null);
098    
099            if (result) {
100                result = playAudioData(audioData);
101            }
102    
103            if (result) {
104                if (DEBUG_ENABLED) {
105                    s_log.debug("OK");
106                }
107            } else {
108                s_log.error("Problems signalling morse.");
109            }
110        }
111    
112        private boolean playAudioData(byte[] audioData) {
113            boolean result = true;
114    
115            try {
116                AudioFormat af = MorseUtil.getAudioFormat();
117                AudioInputStream is = MorseUtil.getAudioInputStream(audioData, af);
118    
119                DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
120                SourceDataLine source = (SourceDataLine) AudioSystem.getLine(info);
121                source.open(af);
122                source.start();
123    
124                byte[] buff = new byte[16384];
125    
126                int i;
127    
128                while ((i = is.read(buff, 0, buff.length)) != -1) {
129                    if (i > 0) {
130                        source.write(buff, 0, i);
131                    }
132                }
133    
134                source.drain();
135                source.stop();
136                source.close();
137            } catch (Exception e) {
138                result = false;
139                s_log.error("Exception", e);
140            }
141    
142            return result;
143        }
144    }