annotate audio/java/StreamSource.java @ 61:eff6bddf82e3 tip

Finally implemented perceptual brightness thing.
author samer
date Sun, 11 Oct 2015 10:20:42 +0100
parents 63cefb01cbab
children
rev   line source
samer@0 1 /*
samer@0 2 * StreamSource.java
samer@0 3 *
samer@0 4 * Copyright (c) 2012, Samer Abdallah, King's College London.
samer@0 5 * All rights reserved.
samer@0 6 *
samer@0 7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0 8 * without even the implied warranty of MERCHANTABILITY or
samer@0 9 * FITNESS FOR A PARTICULAR PURPOSE.
samer@0 10 */
samer@0 11
samer@46 12 package ishara.audio;
samer@0 13 import javax.sound.sampled.*;
samer@0 14 import java.io.*;
samer@0 15
samer@0 16 public class StreamSource extends AudioSource
samer@0 17 {
samer@0 18 InputStream in;
samer@0 19
samer@0 20 public StreamSource(AudioInputStream ain) throws Exception { super(ain.getFormat()); in=ain; }
samer@0 21 public StreamSource(AudioInputStream ain, AudioFormat target) throws Exception {
samer@0 22 this(prepareStream(ain,target));
samer@0 23 }
samer@0 24
samer@0 25 // AudioSource interface methods
samer@0 26 public void dispose() {
samer@0 27 print("Closing audio stream...");
samer@0 28 try { in.close(); } catch (IOException ex) {}
samer@0 29 }
samer@0 30
samer@0 31 public void start() {}
samer@0 32 public void stop() {}
samer@0 33 public int read(byte [] buf, int off, int len) throws Exception {
samer@0 34 return in.read(buf,off,len);
samer@0 35 }
samer@0 36
samer@0 37 public static AudioInputStream prepareStream(AudioInputStream ain, AudioFormat target) throws Exception {
samer@0 38 // convert to target format if required
samer@0 39 print("Preparing audio stream...");
samer@0 40 print(" / audio format: "+ain.getFormat().toString());
samer@0 41 if (target==null) {
samer@0 42 AudioFormat fin=ain.getFormat();
samer@0 43 ain=convertFormat(new AudioFormat( fin.getSampleRate(), 16, fin.getChannels(), true, false), ain);
samer@0 44 } else {
samer@0 45 ain=convertFormat(target, ain);
samer@0 46 }
samer@0 47 print(" \\ final format: "+ain.getFormat().toString());
samer@0 48 return ain;
samer@0 49 }
samer@0 50
samer@0 51 private static AudioInputStream convertVia(AudioFormat fout, AudioInputStream sin, AudioFormat fint) throws Exception
samer@0 52 {
samer@0 53 print(" | Trying recursive via "+fint.toString());
samer@0 54 AudioInputStream sint=AudioSystem.getAudioInputStream(fint,sin);
samer@0 55 AudioFormat fres=sint.getFormat();
samer@0 56 if (!fres.equals(fint)) {
samer@0 57 print(" | obtained "+fres.toString());
samer@0 58 }
samer@0 59 return convertFormat(fout, sint);
samer@0 60 }
samer@0 61
samer@0 62 public static AudioInputStream convertFormat(AudioFormat fout, AudioInputStream sin) throws Exception
samer@0 63 {
samer@0 64 AudioFormat fin=sin.getFormat();
samer@0 65
samer@0 66 if (fin.equals(fout)) return sin;
samer@0 67 if (fin.getEncoding()!=AudioFormat.Encoding.PCM_SIGNED) {
samer@0 68 if (fin.getEncoding().getClass().getName().startsWith("javazoom.spi.")) {
samer@0 69 // these are broken, must go via 16 bit decode with no channels change
samer@0 70 print(" ! Detected noncompliant Javazoom decoder, going via 16 bit.");
samer@0 71 return convertVia( fout, sin, new AudioFormat(
samer@0 72 fin.getSampleRate(), 16, fin.getChannels(), true, fout.isBigEndian()));
samer@0 73 }
samer@0 74
samer@0 75 // first get into PCM encoding, then try recursive
samer@0 76 try {
samer@0 77 return convertVia( fout, sin, new AudioFormat(
samer@0 78 fin.getSampleRate(), fout.getSampleSizeInBits(),
samer@0 79 fin.getChannels(), true, fout.isBigEndian()));
samer@0 80 } catch (IllegalArgumentException ex) {
samer@0 81 print(" * Direct conversion failed");
samer@0 82 }
samer@0 83 return convertVia( fout, sin, new AudioFormat(
samer@0 84 fin.getSampleRate(), fin.getSampleSizeInBits(),
samer@0 85 fin.getChannels(), true, fout.isBigEndian()));
samer@0 86 }
samer@0 87
samer@0 88 if ( !unify(fin.getChannels(),fout.getChannels())
samer@0 89 || !unify(fin.getSampleSizeInBits(),fout.getSampleSizeInBits())) {
samer@0 90 // convert these before doing any sample rate conversion
samer@0 91 return convertVia(fout, sin, new AudioFormat(
samer@0 92 fin.getSampleRate(), fout.getSampleSizeInBits(),
samer@0 93 fout.getChannels(), true, fout.isBigEndian()));
samer@0 94 }
samer@0 95
samer@0 96 // the only thing left is sample rate
samer@0 97 return AudioSystem.getAudioInputStream(fout,sin);
samer@0 98 }
samer@0 99
samer@0 100 private static boolean unify(int x, int y) { return x==-1 || y==-1 || x==y; }
samer@0 101 private static boolean unify(float x, float y) { return x==-1 || y==-1 || x==y; }
samer@0 102 }
samer@0 103