comparison audio/java/StreamSource.java @ 0:672052bd81f8

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