samer@0
|
1 /*
|
samer@0
|
2 * AudioSource.java
|
samer@0
|
3 *
|
samer@0
|
4 * Copyright (c) 2000, 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@0
|
12 package samer.audio;
|
samer@0
|
13 import samer.tools.*;
|
samer@0
|
14
|
samer@0
|
15 /**
|
samer@0
|
16 General interface for objects that can supply an
|
samer@0
|
17 audio stream.
|
samer@0
|
18 */
|
samer@0
|
19
|
samer@0
|
20 public interface AudioSource
|
samer@0
|
21 {
|
samer@0
|
22 boolean isOpen();
|
samer@0
|
23 void open() throws Exception;
|
samer@0
|
24 void close();
|
samer@0
|
25 void dispose();
|
samer@0
|
26
|
samer@0
|
27 /** return a task which reads samples into the given buffer
|
samer@0
|
28 * The idea is that the audio source can choose the right
|
samer@0
|
29 * kind of reader depending on the format of the audio stream,
|
samer@0
|
30 * and then handle the conversion to doubles automatically
|
samer@0
|
31 */
|
samer@0
|
32 Task reader(double buf[], int off, int len);
|
samer@0
|
33 Task reader(float buf[], int off, int len);
|
samer@0
|
34
|
samer@1
|
35 int getChannels();
|
samer@1
|
36 float getRate();
|
samer@1
|
37
|
samer@0
|
38 public static class Util {
|
samer@0
|
39 /* NB. These copying functions allow NEGATIVE offset (off<0). The semantics
|
samer@0
|
40 * of this is are that n values are copied from source to destination, writing
|
samer@0
|
41 * into the destination starting at the negative offset, but that values before
|
samer@0
|
42 * index 0 will never be accessed, hence, they are not actually copied. Only
|
samer@0
|
43 * the last n-off values will be available in dst starting from index 0.
|
samer@0
|
44 * This is useful as it allows block-wise audio input where the block lenght
|
samer@0
|
45 * is smaller than the step length.
|
samer@0
|
46 */
|
samer@0
|
47
|
samer@0
|
48 public static void shortToDoubleMixDown(byte [] src, double [] dst, int off, int n, int m) {
|
samer@0
|
49 double a = (1.0/(m*32768.0)); // scaling factor including division by mixdown factor m
|
samer@0
|
50 int skip = off<0 ? -off : 0;
|
samer@0
|
51 for (int i=2*m*skip, j=off+skip; j<n+off; j++) {
|
samer@0
|
52 dst[j] = 0;
|
samer@0
|
53 for (int k=0; k<m; k++) dst[j] += a*((src[i++]&0xff) | src[i++]<<8);
|
samer@0
|
54 }
|
samer@0
|
55 }
|
samer@0
|
56
|
samer@1
|
57 public static void mediumToDouble(byte [] src, double [] dst, int off, int n) {
|
samer@1
|
58 int i, j;
|
samer@1
|
59 if (off<0) { i= 3*(-off); j=0; } else { i=0; j=off; }
|
samer@1
|
60 while (j<n+off) dst[j++] = (1.0/8388608.0)*((src[i++]&0xff) | src[i++]<<8 | src[i++]<<16);
|
samer@1
|
61 }
|
samer@1
|
62
|
samer@0
|
63 public static void shortToDouble(byte [] src, double [] dst, int off, int n) {
|
samer@0
|
64 int i, j;
|
samer@0
|
65 if (off<0) { i= 2*(-off); j=0; } else { i=0; j=off; }
|
samer@0
|
66 while (j<n+off) dst[j++] = (1.0/32768.0)*((src[i++]&0xff) | src[i++]<<8);
|
samer@0
|
67 }
|
samer@0
|
68
|
samer@0
|
69 public static void byteToDouble(byte [] src, double [] dst, int off, int n) {
|
samer@0
|
70 int i, j;
|
samer@0
|
71 if (off<0) { i= -off; j=0; } else { i=0; j=off; }
|
samer@0
|
72 while (j<n+off) dst[j++] = (1.0/256.0)*(src[i++]&0xff)-128.0;
|
samer@0
|
73 }
|
samer@0
|
74
|
samer@0
|
75 public static void shortToFloatMixDown(byte [] src, float [] dst, int off, int n, int m) {
|
samer@0
|
76 int skip = off<0 ? -off : 0;
|
samer@0
|
77 float a = (1F/(m*32768F)); // scaling factor including division by mixdown factor m
|
samer@0
|
78 for (int i=2*m*skip, j=off+skip; j<n+off; j++) {
|
samer@0
|
79 dst[j] = 0;
|
samer@0
|
80 for (int k=0; k<m; k++) dst[j] += a*((src[i++]&0xff) | src[i++]<<8);
|
samer@0
|
81 }
|
samer@0
|
82 }
|
samer@0
|
83
|
samer@0
|
84 public static void shortToFloat(byte [] src, float [] dst, int off, int n) {
|
samer@0
|
85 int i, j;
|
samer@0
|
86 if (off<0) { i= -2*off; j=0; } else { i=0; j=off; }
|
samer@0
|
87 while (j<n+off) dst[j++] = (1F/32768F)*((src[i++]&0xff) | src[i++]<<8);
|
samer@0
|
88 }
|
samer@0
|
89
|
samer@0
|
90 public static void byteToFloat(byte [] src, float [] dst, int off, int n) {
|
samer@0
|
91 int i, j;
|
samer@0
|
92 if (off<0) { i= -off; j=0; } else { i=0; j=off; }
|
samer@0
|
93 while (j<n+off) dst[j++] = (1F/256F)*(src[i++]&0xff)-128F;
|
samer@0
|
94 }
|
samer@0
|
95 }
|
samer@0
|
96 }
|
samer@0
|
97
|