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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include <stdlib.h>
#include "native.h"
#include "globals.h"
#ifdef COMPILE_PA1SND
# include <endianutils.h>
#endif
static Int32 diffLookup[16] = {
1,3,5,7,9,11,13,15,
-1,-3,-5,-7,-9,-11,-13,-15,
};
static Int32 indexScale[16] = {
0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266,
0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266 /* same value for speedup */
};
static int limit(int val,int min,int max) {
if (val<min) return min;
else if (val>max) return max;
else return val;
}
void pcm2adpcm(Int16 *src, UInt8 *dst, UInt32 length) {
#ifndef COMPILE_PA1SND
/*
if (OPTIONS_TST(kOptDeviceARM)) {
PnoDescriptor pno;
ARMPa1SndType userData = {src, dst, length};
MemPtr armP = _PnoInit(ARM_PA1SND, &pno);
_PnoCall(&pno, &userData);
_PnoFree(&pno, armP);
return;
}
*/
int data,val,diff;
int signal,step;
#else
long chan1, chan2;
long data,val,diff;
long signal,step;
#endif
signal = 0;
step = 0x7F;
length >>= 3; // 16bit stereo -> 4bit mono
do {
// high nibble
#ifdef COMPILE_PA1SND
chan1 = ByteSwap16(*src);
src++;
chan2 = ByteSwap16(*src);
src++;
diff = ((chan1 + chan2) >> 1) - signal;
#else
diff = ((*src++ + *src++) >> 1) - signal;
#endif
diff <<= 3;
diff /= step;
val = abs(diff) >> 1;
if (val > 7) val = 7;
if (diff < 0) val+= 8;
signal+= (step * diffLookup[val]) >> 3;
signal = limit(signal, -32768, 32767);
step = (step * indexScale[val]) >> 8;
step = limit(step, 0x7F, 0x6000);
data = val;
// low nibble
#ifdef COMPILE_PA1SND
chan1 = ByteSwap16(*src);
src++;
chan2 = ByteSwap16(*src);
src++;
diff = ((chan1 + chan2) >> 1) - signal;
#else
diff = ((*src++ + *src++) >> 1) - signal;
#endif
diff <<= 3;
diff /= step;
val = abs(diff) >> 1;
if (val > 7) val = 7;
if (diff < 0) val+= 8;
signal+= (step * diffLookup[val]) >> 3;
signal = limit(signal, -32768, 32767);
step = (step * indexScale[val]) >> 8;
step = limit(step, 0x7F, 0x6000);
data |= val << 4;
*dst++ = (UInt8)data;
} while (--length);
}
|