Ignore:
Timestamp:
10/31/06 11:47:09 (17 years ago)
Author:
r2d
Message:
  • first SV8 decoding, it's VERY BADLY implemented. To enable decoding, MPC_LITTLE_ENDIAN must NOT be defined on 386 (so sv7 doesn't work in the same time). Was just to verify that there is no bug in encoding (found 1 !)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libmpcdec/branches/zorg/src/streaminfo.c

    r70 r81  
    4141static const char na[] = "n.a.";
    4242static const char *versionNames[] = {
    43     na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'", 
     43    na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'",
    4444    "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Extreme'", "'Insane'",
    4545    "'BrainDead'", "'quality 9'", "'quality 10'"
     
    5353}
    5454
    55 /// Reads streaminfo from SV7 header. 
     55/// Reads streaminfo from SV7 header.
    5656static mpc_status
    5757streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_uint32_t HeaderData[8])
     
    107107}
    108108
     109/// Reads streaminfo from SV8 header.
     110static mpc_status
     111streaminfo_read_header_sv8(mpc_streaminfo* si, mpc_reader * p_reader)
     112{
     113        int ret;
     114        mpc_block_t block;
     115        mpc_bits_reader bits_reader = {0, 0};
     116        mpc_uint32_t CRC;
     117        mpc_int32_t header_pos;
     118        unsigned char tmp;
     119        mpc_uint64_t sampleCount = 0;
     120
     121        ret = mpc_find_block(p_reader, &block, "SI", "AD");
     122        if (ret != MPC_STATUS_OK)
     123                return ret;
     124
     125        header_pos = p_reader->tell(p_reader);
     126
     127        // FIXME : add CRC check
     128        CRC = mpc_read_bits(p_reader, &bits_reader, 32);
     129        si->stream_version = mpc_read_bits(p_reader, &bits_reader, 8);
     130
     131        do {
     132                p_reader->read(p_reader, &tmp, 1);
     133                sampleCount = (sampleCount << 7) | (tmp & 0x7F);
     134        } while((tmp & 0x80));
     135
     136        si->frames = (sampleCount + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH;
     137        si->is_true_gapless = 1;
     138        si->last_frame_samples = sampleCount - (si->frames - 1) * MPC_FRAME_LENGTH;
     139        si->sample_freq = samplefreqs[mpc_read_bits(p_reader, &bits_reader, 4)];
     140        si->channels = mpc_read_bits(p_reader, &bits_reader, 4) + 1;
     141        si->max_band = mpc_read_bits(p_reader, &bits_reader, 5) + 1;
     142        // FIXME : this flag will be removed, must be 0
     143        si->is = mpc_read_bits(p_reader, &bits_reader, 1);
     144        si->ms = mpc_read_bits(p_reader, &bits_reader, 1);
     145
     146        si->bitrate            = 0;
     147        si->block_size         = 1;
     148
     149        si->pcm_samples     = sampleCount;
     150        si->average_bitrate = 0;
     151        if (si->pcm_samples > 0)
     152                si->average_bitrate = (si->tag_offset - si->header_position) * 8.0
     153                                *  si->sample_freq / si->pcm_samples;
     154
     155        // seek to the end of the block
     156        p_reader->seek(p_reader, header_pos + block.size);
     157
     158        return MPC_STATUS_OK;
     159}
     160
    109161// reads file header and tags
    110162mpc_status
     
    121173    err = p_reader->seek(p_reader, si->header_position);
    122174    if(!err) return MPC_STATUS_FILE;
    123     err = p_reader->read(p_reader, headerData, 8 * 4);
    124     if(err != 8 * 4) return MPC_STATUS_FILE;
    125     err = p_reader->seek(p_reader, si->header_position + 6 * 4);
    126     if(!err) return MPC_STATUS_FILE;
    127 
    128     err = p_reader->get_size(p_reader);
    129     if(err < 0) return MPC_STATUS_FILE;
    130     si->tag_offset = si->total_file_length = err;
    131 
    132     err = memcmp(headerData, "MP+", 3);
    133     if(err) return MPC_STATUS_INVALIDSV;
     175
     176        // read magic
     177        err = p_reader->read(p_reader, headerData, 4);
     178        if(err != 4) return MPC_STATUS_FILE;
     179
     180        if (memcmp(headerData, "MP+", 3) == 0) {
     181                // SV 4-7
     182                err = p_reader->read(p_reader, headerData + 1, 7 * 4);
     183                if(err != 7 * 4) return MPC_STATUS_FILE;
     184                err = p_reader->seek(p_reader, si->header_position + 6 * 4);
     185                if(!err) return MPC_STATUS_FILE;
     186
     187                err = p_reader->get_size(p_reader);
     188                if(err < 0) return MPC_STATUS_FILE;
     189                si->tag_offset = si->total_file_length = err;
    134190
    135191#ifndef MPC_LITTLE_ENDIAN
    136     {
    137         mpc_uint32_t ptr;
    138         for (ptr = 0; ptr < 8; ptr++)
    139             headerData[ptr] = mpc_swap32(headerData[ptr]);
    140     }
     192                {
     193                        mpc_uint32_t ptr;
     194                        for (ptr = 0; ptr < 8; ptr++)
     195                                headerData[ptr] = mpc_swap32(headerData[ptr]);
     196                }
    141197#endif
    142      si->stream_version = headerData[0] >> 24;
    143 
    144      if ((si->stream_version & 15) >= 8)
    145         return MPC_STATUS_INVALIDSV;
    146      else if ((si->stream_version & 15) == 7)
    147      {
    148         err = streaminfo_read_header_sv7(si, headerData);
    149         if(err < 0) return err;
    150      }
    151 
    152     // estimation, exact value needs too much time
    153     si->pcm_samples     = 1152 * si->frames - 576;
    154     si->average_bitrate = 0;
    155     if (si->pcm_samples > 0)
    156         si->average_bitrate = (si->tag_offset  - si->header_position) * 8.0
    157                             *  si->sample_freq / si->pcm_samples;
    158 
    159     return MPC_STATUS_OK;
     198                si->stream_version = headerData[0] >> 24;
     199
     200                if ((si->stream_version & 15) >= 8)
     201                        return MPC_STATUS_INVALIDSV;
     202                else if ((si->stream_version & 15) == 7) {
     203                        err = streaminfo_read_header_sv7(si, headerData);
     204                        if(err < 0) return err;
     205                }
     206
     207                // estimation, exact value needs too much time
     208                si->pcm_samples     = 1152 * si->frames - 576;
     209                si->average_bitrate = 0;
     210                if (si->pcm_samples > 0)
     211                        si->average_bitrate = (si->tag_offset  - si->header_position) * 8.0
     212                                        *  si->sample_freq / si->pcm_samples;
     213        } else if (memcmp(headerData, "MPCK", 4) == 0) {
     214                // SV 8
     215                printf("sv8\n");
     216                streaminfo_read_header_sv8(si, p_reader);
     217        } else
     218                return MPC_STATUS_INVALIDSV;
     219
     220        return MPC_STATUS_OK;
    160221}
    161222
Note: See TracChangeset for help on using the changeset viewer.