Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Home made decoder, first few samples don't match the original (Read 2757 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Home made decoder, first few samples don't match the original

I am working on a flac decoder, and QLP decoding with residuals seem to work fine now.  It seems the encoder mostly uses QLP, except maybe constant subframes in the beginning of some songs.

My audio player plays just fine, and I made a side by side comparison of the original wav file as I play my decoded flac to check for sample accuracy.  This is not to check if flac actually is lossless or anything, I know it is, but to check if MY implementation is working properly - and it is!  At least almost.

My problem is that the first few frames (frame 1 or also sometimes frame 2) is reported as not decoded correctly by my test routine, but the rest of the song is 100% accurate.

Here is the log I am generating:

Count OK means how many samples were ok during that pass.
Count NOK means how many samples were not ok during that pass.
One pass is 800 samples which is the buffer size I have set AudioQueues (on Mac) to use.
MaxL is the maximum difference of a sample between original and decoded audio for the left channel during that pass.
MaxR is the same for the right channel.
My test routine only reports when there are errors detected during a pass.
As you can see, I have problems with the first two frames, but the rest is 100% ok.

Code: [Select]
UTF8 says frame number 0, file position 8411
Count OK: 8 NOK: 792 MaxL: 139 MaxR: 61
Count OK: 0 NOK: 800 MaxL: 175 MaxR: 103
Count OK: 0 NOK: 800 MaxL: 172 MaxR: 108
Count OK: 0 NOK: 800 MaxL: 128 MaxR: 64
Count OK: 0 NOK: 800 MaxL: 15 MaxR: 3
UTF8 says frame number 1, file position 12641
Count OK: 192 NOK: 608 MaxL: 4 MaxR: 0
UTF8 says frame number 2, file position 18490
UTF8 says frame number 3, file position 24216
UTF8 says frame number 4, file position 30129
UTF8 says frame number 5, file position 36700
UTF8 says frame number 6, file position 43268
UTF8 says frame number 7, file position 49490
UTF8 says frame number 8, file position 56081
UTF8 says frame number 9, file position 62755
UTF8 says frame number 10, file position 68848
UTF8 says frame number 11, file position 74486
UTF8 says frame number 12, file position 80281
UTF8 says frame number 13, file position 85944
etc...  No more errors...


If I select another song in my player, my test routine goes bananas:

Code: [Select]
UTF8 says frame number 975, file position 10115190
UTF8 says frame number 976, file position 10126990
-> New song selected here, and will compare two different songs, which of course will not be ok
UTF8 says frame number 0, file position 8293
Count OK: 0 NOK: 800 MaxL: 9963 MaxR: 11117
Count OK: 0 NOK: 800 MaxL: 10167 MaxR: 11302
Count OK: 0 NOK: 800 MaxL: 9203 MaxR: 10055
Count OK: 0 NOK: 800 MaxL: 7830 MaxR: 8560
Count OK: 0 NOK: 800 MaxL: 7618 MaxR: 8461
UTF8 says frame number 1, file position 11209
Count OK: 0 NOK: 800 MaxL: 7954 MaxR: 8340
Count OK: 0 NOK: 800 MaxL: 19033 MaxR: 19758
Count OK: 0 NOK: 800 MaxL: 24490 MaxR: 24952
Count OK: 0 NOK: 800 MaxL: 20896 MaxR: 20698
Count OK: 0 NOK: 800 MaxL: 20545 MaxR: 20994
Count OK: 0 NOK: 800 MaxL: 21331 MaxR: 22020
UTF8 says frame number 2, file position 14202
Count OK: 0 NOK: 800 MaxL: 24085 MaxR: 25433
Count OK: 0 NOK: 800 MaxL: 18334 MaxR: 19576
Count OK: 0 NOK: 800 MaxL: 19059 MaxR: 19758
Count OK: 0 NOK: 800 MaxL: 22986 MaxR: 24286
Count OK: 0 NOK: 800 MaxL: 26677 MaxR: 26672
Count OK: 0 NOK: 800 MaxL: 17138 MaxR: 18412



My question is if anyone here may have any ideas what kind of bugs I can have made that makes just the few first frames not decode correctly?
It is kind of weird, since the rest of the song is ok, and there is no state information between frames that can mess things up either.

The frames that fail, is QLP, left/right/side/middle correlation varies all the time, and has never been a problem throughout a song.  If it was not QLP, it would be reported in the log, as my implementation for the other sub frame types is not tested properly yet.


Home made decoder, first few samples don't match the original

Reply #1
Oh no... I found a song that have a few snap crackle and pops that are reported as bad in the middle of the song too.  Back to the debugging session it seems.

Documentation (except source code) is hard to find, and recombining the channels is not very well documented in the case of the extra bit for the side channels.  Here is my code:

Code: [Select]
- (void)combineChannels {
    uint64_t blockSize = [frameInfo blockSize];
    if ([frameInfo channelMode] == 0x00) {
        return;
    }
    else if ([frameInfo channelMode] == 0x01) {
        //left / side
        for (uint64_t i = 0; i < blockSize; i++) {
            int64_t left = sampleBuffer[0][i];
            int64_t side = sampleBuffer[1][i];
            sampleBuffer[0][i] = left;
            sampleBuffer[1][i] = left - side;
        }
    }
    else if ([frameInfo channelMode] == 0x02) {
        //right / side
        for (uint64_t i = 0; i < blockSize; i++) {
            int64_t side = sampleBuffer[0][i];
            int64_t right = sampleBuffer[1][i];
            sampleBuffer[0][i] = right + side;
            sampleBuffer[1][i] = right;
        }
    }
    else if ([frameInfo channelMode] == 0x03) {
        //middle / side
        for (uint64_t i = 0; i < blockSize; i++) {
            int64_t mid = sampleBuffer[0][i];
            int64_t side = sampleBuffer[1][i];
            mid -= (side >> 1);
            sampleBuffer[0][i] = mid + side;
            sampleBuffer[1][i] = mid;

//            sampleBuffer[0][i] = (((mid << 1) | (side & 1)) + side) >> 1;
//            sampleBuffer[1][i] = (((mid << 1) | (side & 1)) - side) >> 1;

//            sampleBuffer[0][i] = (((mid << 1) + (side % 2)) + side) >> 1;
//            sampleBuffer[1][i] = (((mid << 1) + (side % 2)) - side) >> 1;
        }
    }
    else {
        NSLog(@"Illegal Channel mode");
    }
}



But I doubt the error is here, since the glitches are so far apart...


Home made decoder, first few samples don't match the original

Reply #2
Rice codes... d'oh...  Seems I missed handling the case where the rice encoding parameter was 0...  Working like a charm now...  Problem solved.