// Path: src/main/java/de/ralleytn/simple/audio/internal/VorbisInputStream.java
// public class VorbisInputStream extends InputStream {
// 
// 	private VorbisStream source;
// 	
// 	/**
// 	 * @param source the instance of {@linkplain VorbisStream} to wrap
// 	 * @since 1.2.2
// 	 */
// 	public VorbisInputStream(VorbisStream source) {
// 		
// 		this.source = source;
// 	}
// 	
// 	@Override
// 	public int read(byte[] buffer) throws IOException {
// 
// 		return this.read(buffer, 0, buffer.length);
// 	}
// 	
// 	@Override
// 	public int read(byte[] buffer, int offset, int length) throws IOException {
// 
// 		try {
// 			
// 			return this.source.readPcm(buffer, offset, length);
// 			
// 		// catch is empty because this code was copied and throwing a RuntimeException could break it
// 		} catch(EndOfOggStreamException exception) {}
// 		
// 		return -1;
// 	}
// 	
// 	@Override
// 	public int read() throws IOException {
// 		
// 		return 0;
// 	}
// 	
// 	/**
// 	 * @return the {@linkplain AudioFormat} of the wrapped {@linkplain VorbisStream}.
// 	 * @since 1.2.2
// 	 */
// 	public AudioFormat getAudioFormat() {
// 		
// 		return new AudioFormat(this.source.getIdentificationHeader().getSampleRate(), 16, this.source.getIdentificationHeader().getChannels(), true, true);
// 	}
// }


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.Control;
import javax.sound.sampled.EnumControl;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import org.tritonus.share.sampled.file.TAudioFileFormat;
import de.jarnbjo.ogg.LogicalOggStream;
import de.jarnbjo.ogg.OnDemandUrlStream;
import de.jarnbjo.vorbis.VorbisStream;
import de.ralleytn.simple.audio.internal.VorbisInputStream;
	
	/**
	 * @param resource the resource from which you want the {@linkplain AudioInputStream} from
	 * @return the {@linkplain AudioInputStream} from the resource
	 * @throws AudioException if something went wrong while retrieving the {@linkplain AudioInputStream}
	 * @since 1.1.0
	 */
	public static AudioInputStream getAudioInputStream(URL resource) throws AudioException {
		
		AudioInputStream audioInputStream = null;
		FileFormat fileFormat = FileFormat.getFormatByName(resource.toExternalForm());
		
		try {
			
			switch(fileFormat) {
				case MP3:
					audioInputStream = AudioSystem.getAudioInputStream(resource);
					AudioFormat baseFormat = audioInputStream.getFormat();
					AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
					audioInputStream = AudioSystem.getAudioInputStream(decodedFormat, audioInputStream);
					break;
	
				case OGG:
					LogicalOggStream loggs = (LogicalOggStream)new OnDemandUrlStream(resource).getLogicalStreams().iterator().next();
					
					if(!loggs.getFormat().equals(LogicalOggStream.FORMAT_VORBIS)) {
						
						throw new AudioException("Not a plain Ogg/Vorbis audio file!");
					}
					
// Path: src/main/java/de/ralleytn/simple/audio/internal/VorbisInputStream.java
// public class VorbisInputStream extends InputStream {
// 
// 	private VorbisStream source;
// 	
// 	/**
// 	 * @param source the instance of {@linkplain VorbisStream} to wrap
// 	 * @since 1.2.2
// 	 */
// 	public VorbisInputStream(VorbisStream source) {
// 		
// 		this.source = source;
// 	}
// 	
// 	@Override
// 	public int read(byte[] buffer) throws IOException {
// 
// 		return this.read(buffer, 0, buffer.length);
// 	}
// 	
// 	@Override
// 	public int read(byte[] buffer, int offset, int length) throws IOException {
// 
// 		try {
// 			
// 			return this.source.readPcm(buffer, offset, length);
// 			
// 		// catch is empty because this code was copied and throwing a RuntimeException could break it
// 		} catch(EndOfOggStreamException exception) {}
// 		
// 		return -1;
// 	}
// 	
// 	@Override
// 	public int read() throws IOException {
// 		
// 		return 0;
// 	}
// 	
// 	/**
// 	 * @return the {@linkplain AudioFormat} of the wrapped {@linkplain VorbisStream}.
// 	 * @since 1.2.2
// 	 */
// 	public AudioFormat getAudioFormat() {
// 		
// 		return new AudioFormat(this.source.getIdentificationHeader().getSampleRate(), 16, this.source.getIdentificationHeader().getChannels(), true, true);
// 	}
// }


// Path: src/main/java/de/ralleytn/simple/audio/AbstractAudio.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.Control;
import javax.sound.sampled.EnumControl;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import org.tritonus.share.sampled.file.TAudioFileFormat;
import de.jarnbjo.ogg.LogicalOggStream;
import de.jarnbjo.ogg.OnDemandUrlStream;
import de.jarnbjo.vorbis.VorbisStream;
import de.ralleytn.simple.audio.internal.VorbisInputStream;

	
	/**
	 * @param resource the resource from which you want the {@linkplain AudioInputStream} from
	 * @return the {@linkplain AudioInputStream} from the resource
	 * @throws AudioException if something went wrong while retrieving the {@linkplain AudioInputStream}
	 * @since 1.1.0
	 */
	public static AudioInputStream getAudioInputStream(URL resource) throws AudioException {
		
		AudioInputStream audioInputStream = null;
		FileFormat fileFormat = FileFormat.getFormatByName(resource.toExternalForm());
		
		try {
			
			switch(fileFormat) {
				case MP3:
					audioInputStream = AudioSystem.getAudioInputStream(resource);
					AudioFormat baseFormat = audioInputStream.getFormat();
					AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
					audioInputStream = AudioSystem.getAudioInputStream(decodedFormat, audioInputStream);
					break;
	
				case OGG:
					LogicalOggStream loggs = (LogicalOggStream)new OnDemandUrlStream(resource).getLogicalStreams().iterator().next();
					
					if(!loggs.getFormat().equals(LogicalOggStream.FORMAT_VORBIS)) {
						
						throw new AudioException("Not a plain Ogg/Vorbis audio file!");
					}
					
					VorbisInputStream vis = new VorbisInputStream(new VorbisStream(loggs));