Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // PS1 SPU-ADPCM decoder
- // A lot of nooooise :'( probably the algorithm is wrong
- // https://dl.dropboxusercontent.com/u/26695489/adpcm/AUDIO.ADPCM
- #include <stdio.h>
- #include <stdint.h>
- #include <assert.h>
- typedef struct {
- int32_t s_1;
- int32_t s_2;
- } AdpcmState;
- const int32_t FILTER0[5] = { 0, 60, 115, 98, 122 };
- const int32_t FILTER1[5] = { 0, 0, -52, -55, -60 };
- const float CurrentVolume = 0.0002f;
- int32_t Clamp(int32_t n, int32_t min, int32_t max)
- {
- if (n < min) return min;
- if (n > max) return max;
- return n;
- }
- int32_t Volume(int32_t n, float volume)
- {
- return (int32_t)((float)n * volume);
- }
- void Decode(int16_t *pOut, uint8_t *pIn, AdpcmState *state)
- {
- int shift = (*pIn & 0x0F);
- int filter = (*pIn >> 4) & 0x0F;
- int flags = pIn[1];
- int32_t f0 = FILTER0[filter];
- int32_t f1 = FILTER1[filter];
- for (int i = 2, nSample = 0; i < 16; i++)
- {
- int data = pIn[i];
- int nl = (signed)((data << 28) & 0xF0000000) >> shift;
- int nh = (signed)((data << 24) & 0xF0000000) >> shift;
- nl += ((f0 * state->s_1) + (f1 * state->s_2) + 32) >> 6;
- nh += ((f0 * nl) + (f1 * state->s_1) + 32) >> 6;
- state->s_2 = nl;
- state->s_1 = nh;
- pOut[nSample++] = Clamp(Volume(nl, CurrentVolume), -32768, +32767);
- pOut[nSample++] = Clamp(Volume(nh, CurrentVolume), -32768, +32767);
- }
- }
- int main()
- {
- uint8_t buf[16];
- int16_t pcm[28];
- AdpcmState state;
- FILE *fIn = fopen("AUDIO.ADPCM", "rb");
- FILE *fOut = fopen("AUDIO.PCM", "wb");
- assert(fIn != NULL);
- assert(fOut != NULL);
- state.s_1 = state.s_2 = 0;
- while (fread(buf, sizeof(buf), 1, fIn) == 1)
- {
- Decode(pcm, buf, &state);
- fwrite(pcm, sizeof(pcm), 1, fOut);
- }
- fclose(fOut);
- fclose(fIn);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement