blob: 5255a221996c8b3e80f9930e3d37b94081267de7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package net.ypresto.androidtranscoder.engine;
import java.nio.ShortBuffer;
public interface AudioRemixer {
void remix(final ShortBuffer inSBuff, final ShortBuffer outSBuff);
AudioRemixer DOWNMIX = new AudioRemixer() {
private static final int SIGNED_SHORT_LIMIT = 32768;
private static final int UNSIGNED_SHORT_MAX = 65535;
@Override
public void remix(final ShortBuffer inSBuff, final ShortBuffer outSBuff) {
// Down-mix stereo to mono
// Viktor Toth's algorithm -
// See: http://www.vttoth.com/CMS/index.php/technical-notes/68
// http://stackoverflow.com/a/25102339
final int inRemaining = inSBuff.remaining() / 2;
final int outSpace = outSBuff.remaining();
final int samplesToBeProcessed = Math.min(inRemaining, outSpace);
for (int i = 0; i < samplesToBeProcessed; ++i) {
// Convert to unsigned
final int a = inSBuff.get() + SIGNED_SHORT_LIMIT;
final int b = inSBuff.get() + SIGNED_SHORT_LIMIT;
int m;
// Pick the equation
if ((a < SIGNED_SHORT_LIMIT) || (b < SIGNED_SHORT_LIMIT)) {
// Viktor's first equation when both sources are "quiet"
// (i.e. less than middle of the dynamic range)
m = a * b / SIGNED_SHORT_LIMIT;
} else {
// Viktor's second equation when one or both sources are loud
m = 2 * (a + b) - (a * b) / SIGNED_SHORT_LIMIT - UNSIGNED_SHORT_MAX;
}
// Convert output back to signed short
if (m == UNSIGNED_SHORT_MAX + 1) m = UNSIGNED_SHORT_MAX;
outSBuff.put((short) (m - SIGNED_SHORT_LIMIT));
}
}
};
AudioRemixer UPMIX = new AudioRemixer() {
@Override
public void remix(final ShortBuffer inSBuff, final ShortBuffer outSBuff) {
// Up-mix mono to stereo
final int inRemaining = inSBuff.remaining();
final int outSpace = outSBuff.remaining() / 2;
final int samplesToBeProcessed = Math.min(inRemaining, outSpace);
for (int i = 0; i < samplesToBeProcessed; ++i) {
final short inSample = inSBuff.get();
outSBuff.put(inSample);
outSBuff.put(inSample);
}
}
};
AudioRemixer PASSTHROUGH = new AudioRemixer() {
@Override
public void remix(final ShortBuffer inSBuff, final ShortBuffer outSBuff) {
// Passthrough
outSBuff.put(inSBuff);
}
};
}
|