import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import java.util.Scanner; /** * This class uses DoubleStacks to reverse .dat sound clips. * @author Jessica Miller * */ public class SoundBlaster { /** * The main method executes by prompting the user for an input file (.dat), * an output file (.dat), and the type of DoubleStack implementation should be * used. Given this information, a reversed sound clip is produced. * @param args * @throws IOException */ public static void main(String[] args) throws IOException { Scanner console = new Scanner(System.in); System.out.println("Welcome to SoundBlaster!!"); Scanner input = getInputFile(console); PrintStream output = getOutputFile(console); boolean useArrayStack = usingArrayStack(console); DoubleStack stack = null; if (useArrayStack) { stack = new ArrayStack(); } else { stack = new LinkedStack(); } int sampleRate = readInput(input, stack); writeOutput(output, stack, sampleRate); } /** * Returns the input file. * @param console * @return * @throws FileNotFoundException */ private static Scanner getInputFile(Scanner console) throws FileNotFoundException { System.out.print("Input file (.dat) to reverse: "); return new Scanner(new File(console.nextLine().trim())); } /** * Returns the output file as a PrintStream. * @param console * @return * @throws FileNotFoundException */ private static PrintStream getOutputFile(Scanner console) throws FileNotFoundException { System.out.print("Output file (.dat) to write backmask to: "); return new PrintStream(new File(console.nextLine().trim())); } /** * Gets the sample rate of the source sound clip and returns it. * @param input * @return */ private static int getSampleRate(Scanner input) { String line = input.nextLine(); Scanner lineScanner = new Scanner(line); lineScanner.next(); // read semicolon lineScanner.next(); // read "Sample" lineScanner.next(); // read "Rate" return lineScanner.nextInt(); // read in sample rate\ } /** * Reads the source .dat file and stores its contents reversec into the passed * DoubleStack. The sample rate found in the source .dat file is returned from this * method. * @param input * @return */ private static int readInput (Scanner input, DoubleStack stack) { // Read the first line of the .dat file. We want to store the // "sample rate" in a variable, but we can ignore the rest // of the line. The fourth token is the one we want (the // sample rate). int sampleRate = getSampleRate(input); // Read in the file and place values from the second column // in the stack. The first column values are thrown away. // We stop reading when we reach the end of the file. int count = 0; while (input.hasNextLine()) { String line = input.nextLine(); if (line.startsWith(";")) { continue; } Scanner lineScanner = new Scanner (line); lineScanner.next(); double data = lineScanner.nextDouble(); stack.push(data); count++; } System.out.println(count + " samples in file"); return sampleRate; } /** * Writes the reversed sound clip to the output file using the DoubleStack that * was created by reading the input. * @param output * @param stack * @param sampleRate */ private static void writeOutput(PrintStream output, DoubleStack stack, int sampleRate) { // Now we are ready to output the data values to output file. // But first, we need to output the header line // "; Sample Rate " output.println("; Sample Rate " + sampleRate); // Since the first column consists of numbers which start // at 0 and increase by 1/sampleRate every time slice, we'll // just use numSteps to recalculate these numbers. int numSteps = 0; // Finally, we print the values in reverse order (by popping // them off the stack). The first column consists of numbers // which start at 0 and increase by 1/sampleRate per row, so // we'll use numSteps/sampleRate to recalculate the appropriate // values. Uniform spacing will be accomplished by printing a tab. while (!stack.isEmpty()) { output.println((double) numSteps / sampleRate + "\t" + stack.peek()); stack.pop(); numSteps++; } } /** * Prompts the user for which DoubleStack implementation should be used to * create the reversed sound file. * @param console * @return */ private static boolean usingArrayStack(Scanner console) { System.out.print("ArrayStack or LinkedStack? "); String answer = console.nextLine(); while (!answer.toLowerCase().startsWith("a") && !answer.toLowerCase().startsWith("l")) { System.out.print("ArrayStack or LinkedStack? "); answer = console.nextLine(); } return answer.toLowerCase().startsWith("a"); } }