Author |
Message |
Jamie
Member |
hi all,
I coded 14 bits player on amiga, and i start to implement adpcm decompression, i have a pc version and i'm curious to know if someone has a better implementation
u16= *pSrc & 15;
predictedValue += IMA_ADPCMStepTable1 [ stepIndex + adpcm ];
stepIndex += IMA_ADPCMIndexTable1[ adpcm ];
if ( stepIndex < 0 ) stepIndex = 0;
if ( stepIndex > 1408 ) stepIndex = 1408;
if ( predictedValue < -0x8000 ) predictedValue = -0x8000;
if ( predictedValue > 0x7fff ) predictedValue = 0x7fff;
*pOut++ = predictedValue;
this code decompress one word
Jamie
|
doom
Member |
Here's a hint: :)
The IMA ADPCM stepsize table is reeeeaaally close to the function:
y = 6.68334 * exp (0.095535 x)
So. Keep your stepsize in a float and multiply by constants rather than move up and down a stepsize table. One step along the table increases the stepsize by a factor of 1.1008. That's on average of course, but I'm pretty sure the integer stepsize table was originally a compromise to be able to make easy hardware implementations of the ADPCM algorithms, and you'd get better sound quality with a smoother curve. Needless to say you'd have to write your own encoder too.
So, that's one way to do it, without the stepsize table. Another is (what I do) to decode two samples with one table lookup. Makes my table about 280k (but it builds quickly at load time). Obviously I assumed the two-samples-at-once thing was worth the cache misses, but I honestly don't know. :)
Also, about your code, consider making predictedValue a float, even if you work with an integer table, cause you get the nice clamping on 68k FPUs. Then your last three lines become:
fmove.w fp0,(a0)+
AND THAT'S AMAZING!
|
Jamie
Member |
i like the fact to replace the stepsize table:)
|
winden
Member |
automatic clamping FTW!!! \o/ nice trick!
|
doom
Member |
Uhm of course he wants to reuse the clamped predictedValue for the next sample. So (try to interleave it of course):
fmove.w fp0,d0
fmove.w d0,fp0
move.w d0,(a0)+
IT'S STILL AMAZING!
|
Jamie
Member |
it's cool but really slower that integer comparaison
|
doom
Member |
Who cares as long as it's cool? ;)
|
rload
Member |
yes.. write it the cool way! don't be boring!
|
Jamie
Member |
speed is important too, and don't be insulting asshole
|
z5_
Member |
and don't be insulting asshole
@jamie: i'm sure it wasn't meant seriously (loaderror being serious would be a first :)).
I hope we can say that we try to have a friendly atmosphere on the ada forums as much as possible.
|
rload
Member |
I think she meant dr. doom was being insulting.
|
z5_
Member |
I think she meant dr. doom was being insulting
shut up loaderror :o) Good thing that epadhrina and IRIS have retired from making demos as Jamie would have humiliated you all so much with his new demo that you would have retired anyway :o)
|
doom
Member |
Where is all this coming from? ;)
|
rload
Member |
I'm just tryign to annoy Jamie a lot and then issue a demo challenge for solskogen so that he cannot refuse :)
|
rload
Member |
But which ADPCM codec is the best? We used Microsoft ADPCM for Lux Aeterna. Tbl used some other codec for their demos.
Slummy/Spaceballs & Dran/Contraz use Brekke/Contraz and Skjeggspir/Contraz's music format which I heard was also about prediction and correction.
Then there is IMA (or is that the same as Microsoft ADPCM?) aswell.
Whats the difference?
|
doom
Member |
http://webstore.ansi.org/ansidocstore/product.asp? sku=T1.TR.35-1994 has a technical comparison of ADPCM algorithms for only $151. :)
Or, look at http://www.multimedia.cx/simpleaudio.html for descriptions of a few time-domain audio compression schemes including IMA and MS ADPCM. No comparison though so you have to actually read both sections. Blech.
Looks like there are some significant diffences though. If I were you, I'd find a representative sound sample, try both encodings in Winamp and convert back to PCM, then subtract each from the original. And then I'd post the results here, with charts and all that. ;)
|
doom
Member |
And BTW I heard that TBL's format was an uncompressed 8-bit mono sample. I forget who said that, though.
|
Kalms
Member |
.unpackSamplePair
move.l d6,d5
muls.l d2,d6
muls.l d3,d7
add.l d0,d6
moveq #0,d0
add.l d7,d6
move.b (a1)+,d0
asr.l #8,d6
asr.l #4, d6
move.l d6,d7
muls.l d2,d6
muls.l d3,d5
add.l d4,d6
move.l d0,d4
add.l d5,d6
move. l d7,(a2)+
asr.l #8,d6
and.b #$f,d0
lsr.b #4 ,d4
asr.l #4,d6
ror.l #4,d0
ror.l #4,d4
mo ve.l d6,(a2)+
asr.l d1,d0
asr.l d1,d4
cmp. l a2,a3
bne.s .unpackSamplePair
Looks like whoever said that was talking out of his arse.
|
Jamie
Member |
Finally after some adpcm test i coded my own encoder. The gTable is 16 value specific for one sound, the encode search the best 16 value possible, sometimes it take some hours:)
u8 adpcm = *_pSrc++;
previousDelta *= gTable[ adpcm >> 4 ];
previousDelta >>= 16;
predictedPcm += previousDelta;
*_pDst++ = (s16) ( predictedPcm );
previousDelta *= gTable[ adpcm & 15 ];
previousDelta >>= 16;
predictedPcm += previousDelta;
*_pDst++ = (s16) ( predictedPcm );
|
doom
Member |
Looks like whoever said that was talking out of his arse.
It would seem so. :)
|
doom
Member |
Finally after some adpcm test i coded my own encoder. The gTable is 16 value specific for one sound, the encode search the best 16 value possible, sometimes it take some hours:)
How do you search through the range of 16 values in a couple of hours? Also, how is the sound quality?
|
Jamie
Member |
i have one process for compute my table, this process take one value in entry, i try a range of value, i save the best value.
The quality is really good, really better that classic adpcm
|
z5_
Member |
@jamie: go go go go!!!! (sorry, but i can't hide my enthusiasm when somebody like Jamie is making a comeback... it would be great)
|
winden
Member |
since a 16 entry table is very small, maybe switching to a new table every N seconds of music maybe could help with gaining much quality while not taking much more space... could also speed up the table-precalc.
btw, for 14bit replay, you just need to set a channel at volume = 64 and another one to 1 volume = 1, don't you?
|
Jamie
Member |
hi Winden,
I had the same idea, but the result is so cool that i don't want to pass more time on the replay routine.
Yep it's exactly what i have, one channel with volume at maximum and one channel with the volume at minimum
|
Jamie
Member |
for the table i want to replace directly in the code with one jmp
jmp case1(pc,d0*(instsize))
.case1:
muls.l #tablevalue1,d0
bra.b .next
.case2:
muls.l #tablevalue2,d0
bra.b .next
etc...
|
doom
Member |
I still don't get it :). The best set of 16 deltas for your sample is some point in 16-dimensional space. So for 16-bit deltas you'd have to encode and decode your sample 2^256 times to find the best table. That's 115,792,089,237,316,195,423,570,985,008,687,907,85 3,269,984,665,640,564,039,457,584,007,913,129,639, 936 times. That's a lot. :)
|
winden
Member |
I think making a histogram with the best values for changes, and then finding the best 16-entry partitioning for that weighted distribution would be a good aproximation for this work.
btw, i wonder if just doing 16bit -> dithered 8bit output instead of 14bit output would be too noticeable... when coding a realtime image dithering last year, a 1bpl SHIRES didn't look that different than a 4bpl LOWRES one...
|
Blueberry
Member |
Emulating 14-bit playback by playing one channel at volume 64 and one at volume 1 is a nice trick - in principle. In reality, the Amiga's D/A converters are quite crappy, so you cannot be sure that a one step in the volume-64 channel corresponds 64 steps in the volume-1 channel. It is different for each sample value (so, for instance, the voltage distance between 63 and 64 will not be the same as between 64 and 65), it is different for each channel, and worst of all, it is different from one Amiga to the next.
The CyberSound calibration tool - http://ftp.wustl.edu/pub/aminet/disk/cdrom/14Bit_C DPlayer.lha - can be used to find out exactly how large the intervals between each sample value pair are. It calibrates the left and right channels at the same time, so it is not as good as it could be, but you will still get much better sound this way than with non-calibrated playback. AHI has a mode for using the calibration info produced by the CyberSound tool.
Sadly, the only way of getting access to this kind of playback in a demo is to use AHI (or just read in the calibration data and use it) and hope that the end user has calibrated his Amiga properly.
|
Jamie
Member |
doom: i use some range value:)
I code on winuae, so i can't do real sound test, on winuae the 14 bits tricks is just perfect, if it's worst maybe a 8 bits sound is the solution
|