1 package net.sf.jack4j.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.nio.ByteBuffer;
23
24
25
26
27
28
29
30 public abstract class IntSampleConverter {
31
32 private static final IntSampleConverter[] converters = { new IntSampleConverter8BitUnsigned(),
33 new IntSampleConverter16BitSignedLittleEndian(), new IntSampleConverter24BitSignedLittleEndian(),
34 new IntSampleConverter32BitSignedLittleEndian() };
35
36 private final static class IntSampleConverter8BitUnsigned extends IntSampleConverter {
37
38 @Override
39 public int bytesPerSample() {
40 return 1;
41 }
42
43 @Override
44 public void floatToIntSample(float sample, ByteBuffer byteBuffer) {
45 int value = (int) (sample * 127 + 128);
46
47 byteBuffer.put((byte) value);
48 }
49
50 @Override
51 public float intSampleToFloat(ByteBuffer byteBuffer) {
52 return (byteBuffer.get() - 128) / 128.0f;
53 }
54
55 @Override
56 public boolean isBigEndian() {
57
58 return false;
59 }
60
61 @Override
62 public boolean isSigned() {
63 return false;
64 }
65
66 }
67
68 private final static class IntSampleConverter16BitSignedLittleEndian extends IntSampleConverter {
69
70 @Override
71 public int bytesPerSample() {
72 return 2;
73 }
74
75 @Override
76 public void floatToIntSample(float sample, ByteBuffer byteBuffer) {
77 int value = (int) (sample * 0x8000);
78 byteBuffer.put((byte) (value & 0xff));
79 byteBuffer.put((byte) ((value >> 8) & 0xff));
80 }
81
82 @Override
83 public float intSampleToFloat(ByteBuffer byteBuffer) {
84 int intValue = ((byteBuffer.get() & 0xff) | (byteBuffer.get() << 8));
85 return ((float) intValue) / 0x8000;
86 }
87
88 @Override
89 public boolean isBigEndian() {
90 return false;
91 }
92
93 @Override
94 public boolean isSigned() {
95 return true;
96 }
97
98 }
99
100 private final static class IntSampleConverter24BitSignedLittleEndian extends IntSampleConverter {
101
102 @Override
103 public int bytesPerSample() {
104 return 3;
105 }
106
107 @Override
108 public void floatToIntSample(float sample, ByteBuffer byteBuffer) {
109 int value = (int) (sample * 0x800000);
110 byteBuffer.put((byte) (value & 0xff));
111 byteBuffer.put((byte) ((value >> 8) & 0xff));
112 byteBuffer.put((byte) ((value >> 16) & 0xff));
113 }
114
115 @Override
116 public float intSampleToFloat(ByteBuffer byteBuffer) {
117 int intValue = ((byteBuffer.get() & 0xff) | (byteBuffer.get() << 8) | (byteBuffer.get() << 16));
118 return ((float) intValue) / 0x800000;
119 }
120
121 @Override
122 public boolean isBigEndian() {
123 return false;
124 }
125
126 @Override
127 public boolean isSigned() {
128 return true;
129 }
130
131 }
132
133 private final static class IntSampleConverter32BitSignedLittleEndian extends IntSampleConverter {
134
135 @Override
136 public int bytesPerSample() {
137 return 4;
138 }
139
140 @Override
141 public void floatToIntSample(float sample, ByteBuffer byteBuffer) {
142 int value = (int) (sample * 0x80000000);
143 byteBuffer.put((byte) (value & 0xff));
144 byteBuffer.put((byte) ((value >> 8) & 0xff));
145 byteBuffer.put((byte) ((value >> 16) & 0xff));
146 byteBuffer.put((byte) ((value >> 24) & 0xff));
147 }
148
149 @Override
150 public float intSampleToFloat(ByteBuffer byteBuffer) {
151 int intValue = ((byteBuffer.get() & 0xff) | (byteBuffer.get() << 8) | (byteBuffer.get() << 16) | (byteBuffer
152 .get() << 24));
153 return ((float) intValue) / 0x80000000;
154 }
155
156 @Override
157 public boolean isBigEndian() {
158 return false;
159 }
160
161 @Override
162 public boolean isSigned() {
163 return true;
164 }
165
166 }
167
168 public static IntSampleConverter createIntSampleConverter(int bitsPerSample, boolean signed, boolean bigEndian) {
169 if ((bitsPerSample <= 0) || (bitsPerSample > 32)) {
170 throw new IllegalArgumentException();
171 }
172
173 int bytesPerSample = (bitsPerSample / 8) + (((bitsPerSample % 8) == 0) ? 0 : 1);
174
175 for (IntSampleConverter converter : converters) {
176 if ((bytesPerSample == converter.bytesPerSample()) && (signed == converter.isSigned())
177 && ((bytesPerSample == 1) || (bigEndian == converter.isBigEndian()))) {
178 return converter;
179 }
180 }
181
182 throw new IllegalArgumentException();
183 }
184
185 public abstract int bytesPerSample();
186
187 public abstract boolean isSigned();
188
189 public abstract boolean isBigEndian();
190
191 public abstract void floatToIntSample(float sample, ByteBuffer byteBuffer);
192
193 public abstract float intSampleToFloat(ByteBuffer byteBuffer);
194 }