Skip to content

Instantly share code, notes, and snippets.

@MrP123
Last active June 16, 2023 12:53
Show Gist options
  • Save MrP123/a0eef7f59cbfa43038fd to your computer and use it in GitHub Desktop.
Save MrP123/a0eef7f59cbfa43038fd to your computer and use it in GitHub Desktop.
package Challenge_177_Intermediate;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.HashMap;
import java.util.Scanner;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public final class MorseCode{
public static final int SAMPLE_RATE = 44100;
private static final int BITS_PER_SAMPLE = 16;
private static final int BYTES_PER_SAMPLE = BITS_PER_SAMPLE / 8;
private static final double MAX_16_BIT = 32767;
private static final int SAMPLE_BUFFER_SIZE = 4096;
private static SourceDataLine line;
private static byte[] buffer;
private static int bufferSize = 0;
private static double freq = 440.0;
private static double[] fullDot;
private static double[] fullDash;
private static double[] pause = note(freq, 0.13, 0);
private static HashMap<Character, String> alphabet = new HashMap<Character, String>();
static{
init();
}
private static void init(){
try{
AudioFormat format = new AudioFormat((float) SAMPLE_RATE, BITS_PER_SAMPLE, 1, true, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE);
buffer = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE / 3];
initSounds();
initHashMap();
}catch(Exception e){
e.printStackTrace();
System.exit(1);
}
line.start();
}
private static void initSounds(){
double[] dot = note(freq, 0.125, 1.0);
double[] dash = note(freq, 0.3, 1.0);
double[] shortPause = note(freq, 0.05, 0);
fullDot = new double[dot.length + shortPause.length];
System.arraycopy(dot, 0, fullDot, 0, dot.length);
System.arraycopy(shortPause, 0, fullDot, dot.length, shortPause.length);
fullDash = new double[dash.length + shortPause.length];
System.arraycopy(dash, 0, fullDash, 0, dash.length);
System.arraycopy(shortPause, 0, fullDash, dash.length, shortPause.length);
}
private static void initHashMap(){
alphabet.put('A', ".-");
alphabet.put('B', "-...");
alphabet.put('C', "-.-.");
alphabet.put('D', "-..");
alphabet.put('E', ".");
alphabet.put('F', "..-.");
alphabet.put('G', "--.");
alphabet.put('H', "....");
alphabet.put('I', "..");
alphabet.put('J', ".---");
alphabet.put('K', "-.-");
alphabet.put('L', ".-..");
alphabet.put('M', "--");
alphabet.put('N', "-.");
alphabet.put('O', "---");
alphabet.put('P', ".--.");
alphabet.put('Q', "--.-");
alphabet.put('R', ".-.");
alphabet.put('S', "...");
alphabet.put('T', "-");
alphabet.put('U', "..-");
alphabet.put('V', "...-");
alphabet.put('W', ".--");
alphabet.put('X', "-..-");
alphabet.put('Y', "-.--");
alphabet.put('Z', "--..");
alphabet.put(' ', "/");
}
public static void close(){
line.drain();
line.stop();
}
public static void play(double in){
if(in < -1.0) in = -1.0;
if(in > +1.0) in = +1.0;
short s = (short) (MAX_16_BIT * in);
buffer[bufferSize++] = (byte) s;
buffer[bufferSize++] = (byte) (s >> 8);
if(bufferSize >= buffer.length){
line.write(buffer, 0, buffer.length);
bufferSize = 0;
}
}
public static void play(double[] input){
for(int i = 0; i < input.length; i++){
play(input[i]);
}
}
public static void save(String filename, double[] input){
AudioFormat format = new AudioFormat(SAMPLE_RATE, 16, 1, true, false);
byte[] data = new byte[2 * input.length];
for(int i = 0; i < input.length; i++){
int temp = (short) (input[i] * MAX_16_BIT);
data[2 * i + 0] = (byte) temp;
data[2 * i + 1] = (byte) (temp >> 8);
}
try{
ByteArrayInputStream bais = new ByteArrayInputStream(data);
AudioInputStream ais = new AudioInputStream(bais, format, input.length);
if(filename.endsWith(".wav")){
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File(filename));
}else{
throw new Exception("File format not supported: " + filename + ". Try *.wav");
}
}catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
private static double[] note(double hz, double duration, double amplitude){
int N = (int) (MorseCode.SAMPLE_RATE * duration);
double[] a = new double[N + 1];
for(int i = 0; i <= N; i++)
a[i] = amplitude * Math.sin(2 * Math.PI * i * hz / MorseCode.SAMPLE_RATE);
return a;
}
private static String generateMorseCode(String text){
String result = "";
for(int i = 0; i < text.length(); i++){
result += alphabet.get(text.charAt(i));
result += " ";
}
return result;
}
private static double[] generateSound(String morseCode){
int dot = 0;
int dash = 0;
int pause = 0;
for(int i = 0; i < morseCode.length(); i++){
switch(morseCode.charAt(i)){
case '.':
dot++;
break;
case '-':
dash++;
break;
case '/':
pause++;
break;
case ' ':
pause++;
break;
}
}
double[] result = new double[dot * MorseCode.fullDot.length + dash * MorseCode.fullDash.length + pause * MorseCode.pause.length];
int index = 0;
for(int i = 0; i < morseCode.length(); i++){
switch(morseCode.charAt(i)){
case '.':
for(int j = 0; j < MorseCode.fullDot.length; j++){
result[index + j] = MorseCode.fullDot[j];
}
index += MorseCode.fullDot.length - 1;
break;
case '-':
for(int j = 0; j < MorseCode.fullDash.length; j++){
result[index + j] = MorseCode.fullDash[j];
}
index += MorseCode.fullDash.length - 1;
break;
case '/':
for(int j = 0; j < MorseCode.pause.length; j++){
result[index + j] = MorseCode.pause[j];
}
index += MorseCode.pause.length - 1;
break;
case ' ':
for(int j = 0; j < MorseCode.pause.length; j++){
result[index + j] = MorseCode.pause[j];
}
index += MorseCode.pause.length - 1;
break;
}
}
return result;
}
public static double[] generate(String text){
text = text.toUpperCase();
String morseCode = generateMorseCode(text);
System.out.println(text + " in morse code: " + morseCode);
return generateSound(morseCode);
}
public static void main(String[] args){
Scanner s = new Scanner(System.in);
System.out.println("Enter your message in the console!");
String message = s.nextLine();
s.close();
save(System.getProperty("user.home") + "/Desktop/Morse_Code.wav", generate(message));
System.out.println("Done");
MorseCode.close();
System.exit(0);
}
}
@FedorSabeshkin
Copy link

Hello!

Thanks for your code, but in map mistake for
alphabet.put('U', "..--");

Must be only one dash
alphabet.put('U', "..-");

@MrP123
Copy link
Author

MrP123 commented Jun 16, 2023

Thanks for pointing that mistake out!
It's fun to see someone having a look at some of my code that is already almost a decade old.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment