PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
adpcm.c
1/*
2
3 PSX VAG-Packer, hacked by bITmASTER@bigfoot.com
4 v0.1
5
6 * Support for looping, better support for wave files,
7 support for stereo samples and some other minor
8 changes and fixes.
9 Lukasz Bruun (mail@lukasz.dk) 2005
10
11
12VAG Info by bITmASTER:
13
14VAG-Sample
15One sample is 16 bits long.
16
17typedef struct {
18 unsigned char pack_info;
19 unsigned char flags;
20 unsigned char packed[14];
21}
22
23pack_info:
24high nibble: Predictor-Number
25low nibble : Shiftfactor
26
27flags:
280x07: Sample-End (Last sample)
290x02: Sample belongs to Repeat-Part
30
310x06: Repeat-Start (First sample)
320x04: Repeat-Point
330x03: Loop Sample-End, begin playing Repeat-Start (2nd last sample)
340x01: Sample-End (2nd last sample)
35
36*/
37
38#include <stdio.h>
39#include <errno.h>
40#include <string.h>
41#include <ctype.h>
42#include <math.h>
43
44#define BUFFER_SIZE 128*28
45
46static short samples[BUFFER_SIZE];
47static char wave[BUFFER_SIZE * 2];
48
49static void find_predict( short *samples, double *d_samples, int *predict_nr, int *shift_factor );
50static void pack( const double *d_samples, short *four_bit, int predict_nr, int shift_factor );
51
52int adpcm_encode(FILE* fp, FILE* sad, int offset, int sample_len, int flag_loop, int bytes_per_sample)
53{
54 short *ptr;
55 double d_samples[28];
56 short four_bit[28];
57 int predict_nr;
58 int shift_factor;
59 int flags;
60 int i, j, k;
61 unsigned char d;
62
63 flags = 0;
64 shift_factor = 0;
65 predict_nr = 0;
66
67 // sample_len is number of 16 bit samples
68 while( sample_len > 0 )
69 {
70 int size;
71
72 // Size is sample_len
73 size = ( sample_len >= BUFFER_SIZE ) ? BUFFER_SIZE : sample_len;
74
75 if(offset)
76 {
77 for(i = 0; i < size; i++)
78 {
79 if(fread( wave+i, bytes_per_sample, 1, fp )==1){
80 fseek(fp, offset, SEEK_CUR);
81 }
82 else{
83 printf("Error: Can't read SAMPLE DATA in WAVE-file.\n");
84 return EIO;
85 }
86 }
87 }
88 else
89 {
90 if(fread(wave, bytes_per_sample, size, fp)!=size){
91 printf("Error: Can't read SAMPLE DATA in WAVE-file.\n");
92 return EIO;
93 }
94 }
95
96 if (bytes_per_sample == 1) {
97 for(i = 0; i < size; i++)
98 {
99 samples[i] = wave[i];
100 samples[i] ^= 0x80;
101 samples[i] <<= 8;
102 }
103 } else {
104 memcpy(samples, wave, BUFFER_SIZE*2);
105 }
106
107 // i = num of samples with size 28
108 i = size / 28;
109
110 // Add blanks
111 if ( size % 28 )
112 {
113 for ( j = size % 28; j < 28; j++ ) samples[28*i+j] = 0;
114 i++;
115 }
116
117 // pack 28 samples
118 for ( j = 0; j < i; j++ )
119 {
120 ptr = samples + j * 28;
121
122 find_predict( ptr, d_samples, &predict_nr, &shift_factor );
123
124 // pack samples
125 pack( d_samples, four_bit, predict_nr, shift_factor );
126
127 // correctly format predict_nr and shift_factor and write to file
128 d = ( predict_nr << 4 ) | shift_factor;
129 fputc( d, sad );
130
131 if(flag_loop == 1)
132 {
133 fputc( 6, sad );; // loop value
134 flag_loop = 2;
135 }
136 else
137 {
138 fputc( flags, sad );
139 }
140
141 // Write the 28 samples to file
142 for ( k = 0; k < 28; k += 2 )
143 {
144 d = ( ( four_bit[k+1] >> 8 ) & 0xf0 ) | ( ( four_bit[k] >> 12 ) & 0xf );
145 fputc( d, sad );
146 }
147
148 // Decrease sample_len by 28 samples
149 sample_len -= 28;
150
151 if ( sample_len < 28 )
152 {
153 if(flag_loop == 2)
154 flags = 3;
155 else
156 flags = 1;
157 }
158 }
159 }
160
161 fputc( ( predict_nr << 4 ) | shift_factor, sad );
162 fputc( 7, sad ); // end flag
163
164 for ( i = 0; i < 14; i++ )
165 fputc( 0, sad );
166
167 return 0;
168}
169
170
171static double f[5][2] = { { 0.0, 0.0 },
172 { -60.0 / 64.0, 0.0 },
173 { -115.0 / 64.0, 52.0 / 64.0 },
174 { -98.0 / 64.0, 55.0 / 64.0 },
175 { -122.0 / 64.0, 60.0 / 64.0 } };
176
177
178
179static void find_predict( short *samples, double *d_samples, int *predict_nr, int *shift_factor )
180{
181 int i, j;
182 double buffer[28][5];
183 double min = 1e10;
184 double max[5];
185 double ds;
186 int min2;
187 int shift_mask;
188 static double _s_1 = 0.0; // s[t-1]
189 static double _s_2 = 0.0; // s[t-2]
190 double s_0, s_1, s_2;
191
192 for ( i = 0; i < 5; i++ ) {
193 max[i] = 0.0;
194 s_1 = _s_1;
195 s_2 = _s_2;
196 for ( j = 0; j < 28; j ++ ) {
197 s_0 = (double) samples[j]; // s[t-0]
198 if ( s_0 > 30719.0 )
199 s_0 = 30719.0;
200 if ( s_0 < - 30720.0 )
201 s_0 = -30720.0;
202 ds = s_0 + s_1 * f[i][0] + s_2 * f[i][1];
203 buffer[j][i] = ds;
204 if ( fabs( ds ) > max[i] )
205 max[i] = fabs( ds );
206// printf( "%+5.2f\n", s2 );
207 s_2 = s_1; // new s[t-2]
208 s_1 = s_0; // new s[t-1]
209 }
210
211 if ( max[i] < min ) {
212 min = max[i];
213 *predict_nr = i;
214 }
215 if ( min <= 7 ) {
216 *predict_nr = 0;
217 break;
218 }
219
220 }
221
222// store s[t-2] and s[t-1] in a static variable
223// these than used in the next function call
224
225 _s_1 = s_1;
226 _s_2 = s_2;
227
228 for ( i = 0; i < 28; i++ )
229 d_samples[i] = buffer[i][*predict_nr];
230
231// if ( min > 32767.0 )
232// min = 32767.0;
233
234 min2 = ( int ) min;
235 shift_mask = 0x4000;
236 *shift_factor = 0;
237
238 while( *shift_factor < 12 ) {
239 if ( shift_mask & ( min2 + ( shift_mask >> 3 ) ) )
240 break;
241 (*shift_factor)++;
242 shift_mask = shift_mask >> 1;
243 }
244
245}
246
247static void pack( const double *d_samples, short *four_bit, int predict_nr, int shift_factor )
248{
249 static double s_1 = 0.0;
250 static double s_2 = 0.0;
251 int i;
252
253 for ( i = 0; i < 28; i++ ) {
254 double ds;
255 int di, di_shift_tmp;
256 double s_0;
257
258 s_0 = d_samples[i] + s_1 * f[predict_nr][0] + s_2 * f[predict_nr][1];
259 ds = s_0 * (double) ( 1 << shift_factor );
260
261 di = ( (int) ds + 0x800 ) & 0xfffff000;
262
263 if ( di > 32767 )
264 di = 32767;
265 if ( di < -32768 )
266 di = -32768;
267
268 four_bit[i] = (short) di;
269
270 // This is a portable implementation of arithmetic right shift.
271 di_shift_tmp = -((unsigned int) di >> 31);
272 di = (di_shift_tmp ^ di) >> shift_factor ^ di_shift_tmp;
273 s_2 = s_1;
274 s_1 = (double) di - s_0;
275
276 }
277}
278
#define EIO
Definition errno.h:29