BVB Source Codes

cmus Show nomad.c Source code

Return Download cmus: download nomad.c Source code - Download cmus Source code - Type:.c
  1. /*
  2.  * Copyright 2008-2013 Various Authors
  3.  * Copyright 2004-2005 Timo Hirvonen
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License as
  7.  * published by the Free Software Foundation; either version 2 of the
  8.  * License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. /*
  20.  * Gapless decoding added by Chun-Yu Shei <cshei AT cs.indiana.edu>
  21.  */
  22.  
  23. /*
  24.  * Xing code copied from xmms-mad plugin.
  25.  * Lame code copied from mpd
  26.  */
  27.  
  28. #include "nomad.h"
  29. #include "id3.h"
  30. #include "xmalloc.h"
  31. #include "debug.h"
  32. #include "misc.h"
  33.  
  34. #include <mad.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <math.h>
  38. #include <unistd.h>
  39. #include <string.h>
  40. #include <errno.h>
  41.  
  42. #define INPUT_BUFFER_SIZE       (5 * 8192)
  43. #define SEEK_IDX_INTERVAL       15
  44.  
  45. /* the number of samples of silence the decoder inserts at start */
  46. #define DECODERDELAY            529
  47.  
  48. #define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
  49. #define INFO_MAGIC (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o')
  50.  
  51. struct seek_idx_entry {
  52.         off_t offset;
  53.         mad_timer_t timer;
  54. };
  55.  
  56. struct nomad {
  57.         struct mad_stream stream;
  58.         struct mad_frame frame;
  59.         struct mad_synth synth;
  60.         mad_timer_t timer;
  61.         unsigned long cur_frame;
  62.         off_t input_offset;
  63.         /* MAD_BUFFER_GUARD zeros are required at the end of the stream to decode the last frame
  64.            ref: http://www.mars.org/mailman/public/mad-dev/2001-May/000262.html */
  65.         unsigned char input_buffer[INPUT_BUFFER_SIZE + MAD_BUFFER_GUARD];
  66.         int i;
  67.         unsigned int has_xing : 1;
  68.         unsigned int has_lame : 1;
  69.         unsigned int seen_first_frame : 1;
  70.         unsigned int readEOF : 1;
  71.         int start_drop_frames;
  72.         int start_drop_samples;
  73.         int end_drop_samples;
  74.         int end_drop_frames;
  75.  
  76.         struct nomad_xing xing;
  77.         struct nomad_lame lame;
  78.  
  79.         struct {
  80.                 int size;
  81.                 struct seek_idx_entry *table;
  82.         } seek_idx;
  83.  
  84.         struct {
  85.                 unsigned long long int bitrate_sum;
  86.                 unsigned long nr_frames;
  87.         } current;
  88.  
  89.         struct nomad_info info;
  90.         void *datasource;
  91.         int datasource_fd;
  92.         struct nomad_callbacks cbs;
  93. };
  94.  
  95. static inline int scale(mad_fixed_t sample)
  96. {
  97.         sample += 1L << (MAD_F_FRACBITS - 16);
  98.         if (sample >= MAD_F_ONE) {
  99.                 sample = MAD_F_ONE - 1;
  100.         } else if (sample < -MAD_F_ONE) {
  101.                 sample = -MAD_F_ONE;
  102.         }
  103.         return sample >> (MAD_F_FRACBITS - 15);
  104. }
  105.  
  106. static inline double timer_to_seconds(mad_timer_t timer)
  107. {
  108.         signed long ms;
  109.  
  110.         ms = mad_timer_count(timer, MAD_UNITS_MILLISECONDS);
  111.         return (double)ms / 1000.0;
  112. }
  113.  
  114. static int parse_lame(struct nomad *nomad, struct mad_bitptr ptr, int bitlen)
  115. {
  116.         int i, adj = 0;
  117.         unsigned int version_major, version_minor;
  118.         float val;
  119.  
  120.         /* Unlike the xing header, the lame tag has a fixed length.  Fail if
  121.          * not all 36 bytes (288 bits) are there. */
  122.         if (bitlen < 288) return 0;
  123.  
  124.         for (i = 0; i < 9; i++) nomad->lame.encoder[i] = (char)mad_bit_read(&ptr, 8);
  125.         nomad->lame.encoder[9] = '\0';
  126.  
  127.         /* This is technically incorrect, since the encoder might not be lame.
  128.          * But there's no other way to determine if this is a lame tag, and we
  129.          * wouldn't want to go reading a tag that's not there. */
  130.         if (strncmp(nomad->lame.encoder, "LAME", 4) != 0) return 0;
  131.  
  132.         if (sscanf(nomad->lame.encoder + 4, "%u.%u", &version_major, &version_minor) != 2)
  133.                 return 0;
  134.  
  135. #if defined(DEBUG_LAME)
  136.         d_print("detected LAME version %s\n", nomad->lame.encoder + 4);
  137. #endif
  138.  
  139.         i = mad_bit_read(&ptr, 4);
  140. #if defined(DEBUG_LAME)
  141.         d_print("LAME tag revision: %d\n", i);
  142. #endif
  143.         nomad->lame.vbr_method = mad_bit_read(&ptr, 4);
  144.  
  145.         /* ReplayGain in LAME tag was added in 3.94 */
  146.         if (version_major > 3 || (version_major == 3 && version_minor >= 94)) {
  147.                 /* lowpass */
  148.                 mad_bit_read(&ptr, 8);
  149.  
  150.                 /* The reference volume was changed from the 83dB used in the
  151.                  * ReplayGain spec to 89dB in lame 3.95.1.  Bump the gain for older
  152.                  * versions, since everyone else uses 89dB instead of 83dB.
  153.                  * Unfortunately, lame didn't differentiate between 3.95 and 3.95.1, so
  154.                  * it's impossible to make the proper adjustment for 3.95.
  155.                  * Fortunately, 3.95 was only out for about a day before 3.95.1 was
  156.                  * released. -- tmz */
  157.                 if (version_major < 3 || (version_major == 3 && version_minor < 95))
  158.                         adj = 6;
  159.  
  160.                 val = mad_bit_read(&ptr, 32) / (float) (1 << 23);
  161.                 /* peak value of 0.0 means lame didn't calculate the peak at all
  162.                  * (--replaygain-fast), even silence has a value > 0.0 */
  163.                 if (val)
  164.                         nomad->lame.peak = val;
  165.                 for (i = 0; i < 2; i++) {
  166.                         int gain, gain_type;
  167.                         gain_type = replaygain_decode(mad_bit_read(&ptr, 16), &gain);
  168.                         val = gain / 10.f + adj;
  169.                         if (gain_type == 1)
  170.                                 nomad->lame.trackGain = val;
  171.                         /* LAME currently doesn't store any album gain!
  172.                         else if (gain_type == 2)
  173.                                 nomad->lame.albumGain = val;
  174.                         */
  175.                 }
  176.  
  177.                 /*
  178.                  * 4 encoding flags
  179.                  * 4 ATH type
  180.                  * 8 minimal bitrate (if ABR -> specified bitrate)
  181.                  */
  182.                 mad_bit_read(&ptr, 16);
  183.         } else
  184.                 mad_bit_read(&ptr, 88);
  185.  
  186.         nomad->lame.encoderDelay = mad_bit_read(&ptr, 12);
  187.         nomad->lame.encoderPadding = mad_bit_read(&ptr, 12);
  188. #if defined(DEBUG_LAME)
  189.         if (adj > 0)
  190.                 d_print("adjusted gains by %+d dB (old LAME)\n", adj);
  191.         if (!isnan(nomad->lame.peak))
  192.                 d_print("peak: %f\n", nomad->lame.peak);
  193.         if (!isnan(nomad->lame.trackGain))
  194.                 d_print("trackGain: %+.1f dB\n", nomad->lame.trackGain);
  195.         if (!isnan(nomad->lame.albumGain))
  196.                 d_print("albumGain: %+.1f dB\n", nomad->lame.albumGain);
  197.         d_print("encoderDelay: %d, encoderPadding: %d\n", nomad->lame.encoderDelay, nomad->lame.encoderPadding);
  198. #endif
  199.  
  200.         mad_bit_read(&ptr, 96);
  201.  
  202.         nomad->start_drop_frames = 1;   /* XING/LAME header is an empty frame */
  203.         nomad->start_drop_samples = nomad->lame.encoderDelay + DECODERDELAY;
  204.         nomad->end_drop_samples = nomad->lame.encoderPadding - DECODERDELAY;
  205.  
  206.         nomad->has_lame = 1;
  207.  
  208.         return 1;
  209. }
  210.  
  211. /*
  212.  * format:
  213.  *
  214.  *   4 "Xing"
  215.  *   4 flags
  216.  *   4 frames (optional)
  217.  *   4 bytes  (optional)
  218.  * 100 TOC    (optional)
  219.  *   4 scale  (optional)
  220.  */
  221. static int xing_parse(struct nomad *nomad)
  222. {
  223.         struct mad_bitptr ptr = nomad->stream.anc_ptr;
  224.         struct mad_bitptr start = ptr;
  225.         int oldbitlen = nomad->stream.anc_bitlen;
  226.         int bitlen = nomad->stream.anc_bitlen;
  227.         int bitsleft;
  228.         unsigned xing_id;
  229.  
  230.         nomad->has_xing = 0;
  231.         nomad->has_lame = 0;
  232.         if (bitlen < 64)
  233.                 return -1;
  234.         xing_id = mad_bit_read(&ptr, 32);
  235.         if (xing_id != XING_MAGIC && xing_id != INFO_MAGIC) {
  236.                 /*
  237.                  * Due to an unfortunate historical accident, a Xing VBR tag
  238.                  * may be misplaced in a stream with CRC protection. We check
  239.                  * for this by assuming the tag began two octets prior and the
  240.                  * high bits of the following flags field are always zero.
  241.                  */
  242.                 if (xing_id != (((XING_MAGIC+0UL) << 16) & 0xffffffffL) &&
  243.                                 xing_id != (((INFO_MAGIC+0UL) << 16) & 0xffffffffL))
  244.                         return -1;
  245.                 xing_id >>= 16;
  246.                 ptr = start;
  247.                 mad_bit_skip(&ptr, 16);
  248.                 bitlen += 16;
  249.         }
  250.         nomad->xing.is_info = ((xing_id & 0x0000ffffL) == (INFO_MAGIC & 0x0000ffffL));
  251.         nomad->xing.flags = mad_bit_read(&ptr, 32);
  252.         bitlen -= 64;
  253.         if (nomad->xing.flags & XING_FRAMES) {
  254.                 if (bitlen < 32)
  255.                         return -1;
  256.                 nomad->xing.nr_frames = mad_bit_read(&ptr, 32);
  257.                 bitlen -= 32;
  258.         }
  259.         if (nomad->xing.flags & XING_BYTES) {
  260.                 if (bitlen < 32)
  261.                         return -1;
  262.                 nomad->xing.bytes = mad_bit_read(&ptr, 32);
  263.                 bitlen -= 32;
  264.         }
  265.         if (nomad->xing.flags & XING_TOC) {
  266.                 int i;
  267.  
  268.                 if (bitlen < 800)
  269.                         return -1;
  270.                 for (i = 0; i < 100; i++)
  271.                         nomad->xing.toc[i] = mad_bit_read(&ptr, 8);
  272.                 bitlen -= 800;
  273.         }
  274.         if (nomad->xing.flags & XING_SCALE) {
  275.                 if (bitlen < 32)
  276.                         return -1;
  277.                 nomad->xing.scale = mad_bit_read(&ptr, 32);
  278.                 bitlen -= 32;
  279.         }
  280.  
  281.         /* Make sure we consume no less than 120 bytes (960 bits) in hopes that
  282.          * the LAME tag is found there, and not right after the Xing header */
  283.         bitsleft = 960 - (oldbitlen - bitlen);
  284.         if (bitsleft < 0) return -1;
  285.         else if (bitsleft > 0) {
  286.                 mad_bit_read(&ptr, bitsleft);
  287.                 bitlen -= bitsleft;
  288.         }
  289.  
  290.         nomad->has_xing = 1;
  291. #if defined(DEBUG_XING)
  292.         if (nomad->xing.flags & XING_FRAMES)
  293.                 d_print("frames: %d (xing)\n", nomad->xing.nr_frames);
  294. #endif
  295.  
  296.         parse_lame(nomad, ptr, bitlen);
  297.  
  298.         return 0;
  299. }
  300.  
  301. /*
  302.  * returns:
  303.  *    0: eof
  304.  *   -1: error
  305.  *   >0: ok
  306.  */
  307. static int fill_buffer(struct nomad *nomad)
  308. {
  309.         if (nomad->stream.buffer == NULL || nomad->stream.error == MAD_ERROR_BUFLEN) {
  310.                 ssize_t read_size, remaining, len;
  311.                 unsigned char *read_start;
  312.  
  313.                 if (nomad->stream.next_frame != NULL) {
  314.                         remaining = nomad->stream.bufend - nomad->stream.next_frame;
  315.                         memmove(nomad->input_buffer, nomad->stream.next_frame, remaining);
  316.                         read_start = nomad->input_buffer + remaining;
  317.                         read_size = INPUT_BUFFER_SIZE - remaining;
  318.                 } else {
  319.                         read_size = INPUT_BUFFER_SIZE;
  320.                         read_start = nomad->input_buffer;
  321.                         remaining = 0;
  322.                 }
  323.                 read_size = nomad->cbs.read(nomad->datasource, read_start, read_size);
  324.                 if (read_size == -1) {
  325.                         if (errno != EAGAIN)
  326.                                 d_print("read error on bitstream (%d:%s)\n", errno, strerror(errno));
  327.                         return -1;
  328.                 }
  329.                 if (read_size == 0) {
  330.                         if (!nomad->readEOF) {
  331.                                 memset(nomad->input_buffer + remaining, 0, MAD_BUFFER_GUARD);
  332.                                 remaining += MAD_BUFFER_GUARD;
  333.                                 d_print("hit end of stream, appended MAD_BUFFER_GUARD zeros\n");
  334.                                 nomad->readEOF = 1;
  335.                         }
  336.                         else return 0;
  337.                 }
  338.  
  339.                 len = read_size + remaining;
  340.  
  341.                 nomad->input_offset += read_size;
  342.  
  343.                 mad_stream_buffer(&nomad->stream, nomad->input_buffer, len);
  344.                 nomad->stream.error = 0;
  345.         }
  346.         return 1;
  347. }
  348.  
  349. static void handle_lost_sync(struct nomad *nomad)
  350. {
  351.         unsigned long frame;
  352.         int size;
  353.  
  354.         frame = nomad->cur_frame;
  355.         if (frame == 0) {
  356.                 /* cur_frame is not set when scanning file */
  357.                 frame = nomad->info.nr_frames;
  358.         }
  359.  
  360.         size = id3_tag_size((const char *)nomad->stream.this_frame,
  361.                         nomad->stream.bufend - nomad->stream.this_frame);
  362.         if (size > 0) {
  363.                 d_print("frame %ld, skipping ID3 tag (%d bytes)\n", frame, size);
  364.                 mad_stream_skip(&nomad->stream, size);
  365.         } else {
  366.                 d_print("frame %ld\n", frame);
  367.         }
  368. }
  369.  
  370.  
  371. /* Builds a seek index as the file is decoded
  372.  * NOTE: increases nomad->timer (current position)
  373.  */
  374. static void build_seek_index(struct nomad *nomad)
  375. {
  376.         mad_timer_t timer_now = nomad->timer;
  377.         off_t offset;
  378.         int idx;
  379.  
  380.         mad_timer_add(&nomad->timer, nomad->frame.header.duration);
  381.  
  382.         if (nomad->has_xing)
  383.                 return;
  384.  
  385.         if (nomad->timer.seconds < (nomad->seek_idx.size + 1) * SEEK_IDX_INTERVAL)
  386.                 return;
  387.  
  388.         /* offset = ftell() */
  389.         offset = nomad->input_offset;
  390.         /* subtract by buffer length to get offset to start of buffer */
  391.         offset -= (nomad->stream.bufend - nomad->input_buffer);
  392.         /* then add offset to the current frame */
  393.         offset += (nomad->stream.this_frame - nomad->input_buffer);
  394.  
  395.         idx = nomad->seek_idx.size;
  396.  
  397.         nomad->seek_idx.table = xrenew(struct seek_idx_entry, nomad->seek_idx.table, idx + 1);
  398.         nomad->seek_idx.table[idx].offset = offset;
  399.         nomad->seek_idx.table[idx].timer = timer_now;
  400.  
  401.         nomad->seek_idx.size++;
  402. }
  403.  
  404. static void calc_frames_fast(struct nomad *nomad)
  405. {
  406.         if (nomad->has_xing && (nomad->xing.flags & XING_FRAMES) && nomad->xing.nr_frames) {
  407.                 nomad->info.nr_frames = nomad->xing.nr_frames;
  408.                 mad_timer_multiply(&nomad->timer, nomad->info.nr_frames);
  409.         } else {
  410.                 nomad->info.nr_frames = nomad->info.filesize /
  411.                         (nomad->stream.next_frame - nomad->stream.this_frame);
  412.                 mad_timer_multiply(&nomad->timer, nomad->info.nr_frames);
  413.         }
  414. }
  415.  
  416. static void calc_bitrate_fast(struct nomad *nomad)
  417. {
  418.         nomad->info.vbr = nomad->has_xing ? !nomad->xing.is_info : 0;
  419.  
  420.         if (nomad->has_lame && nomad->lame.vbr_method == 1)
  421.                 nomad->info.vbr = 0;
  422.  
  423.         if (nomad->has_xing && (nomad->xing.flags & XING_BYTES) && nomad->xing.bytes)
  424.                 nomad->info.avg_bitrate = (nomad->xing.bytes * 8.0) / nomad->info.duration;
  425.         else
  426.                 nomad->info.avg_bitrate = nomad->frame.header.bitrate;
  427. }
  428.  
  429. /*
  430.  * fields
  431.  *     nomad->info.avg_bitrate and
  432.  *     nomad->info.vbr
  433.  * are only estimated
  434.  */
  435. static int scan(struct nomad *nomad)
  436. {
  437.         struct mad_header *header = &nomad->frame.header;
  438.  
  439.         while (1) {
  440.                 int rc;
  441.  
  442.                 rc = fill_buffer(nomad);
  443.                 if (rc == -1)
  444.                         return -1;
  445.                 if (rc == 0)
  446.                         break;
  447.  
  448.                 if (mad_frame_decode(&nomad->frame, &nomad->stream) == -1) {
  449.                         if (nomad->stream.error == MAD_ERROR_BUFLEN)
  450.                                 continue;
  451.                         if (!MAD_RECOVERABLE(nomad->stream.error)) {
  452.                                 d_print("unrecoverable frame level error.\n");
  453.                                 return -1;
  454.                         }
  455.                         if (nomad->stream.error == MAD_ERROR_LOSTSYNC)
  456.                                 handle_lost_sync(nomad);
  457.                         continue;
  458.                 }
  459.  
  460.                 build_seek_index(nomad);
  461.  
  462.                 // first valid frame
  463.                 nomad->info.sample_rate = header->samplerate;
  464.                 nomad->info.channels = MAD_NCHANNELS(header);
  465.                 nomad->info.layer = header->layer;
  466.                 nomad->info.dual_channel = header->mode == MAD_MODE_DUAL_CHANNEL;
  467.                 nomad->info.joint_stereo = header->mode == MAD_MODE_JOINT_STEREO;
  468.  
  469.                 xing_parse(nomad);
  470.                 calc_frames_fast(nomad);
  471.                 break;
  472.         }
  473.         if (nomad->info.nr_frames == 0) {
  474.                 d_print("error: not an mp3 file!\n");
  475.                 return -NOMAD_ERROR_FILE_FORMAT;
  476.         }
  477.         nomad->info.duration = timer_to_seconds(nomad->timer);
  478.         calc_bitrate_fast(nomad);
  479.         nomad->cur_frame = 0;
  480.         nomad->cbs.lseek(nomad->datasource, 0, SEEK_SET);
  481.         nomad->input_offset = 0;
  482.         return 0;
  483. }
  484.  
  485. static int decode(struct nomad *nomad)
  486. {
  487.         int rc;
  488.  
  489. start:
  490.         rc = fill_buffer(nomad);
  491.         if (rc == -1)
  492.                 return -1;
  493.         if (rc == 0)
  494.                 return 1;
  495.  
  496.         if (mad_frame_decode(&nomad->frame, &nomad->stream)) {
  497.                 if (nomad->stream.error == MAD_ERROR_BUFLEN)
  498.                         goto start;
  499.                 if (!MAD_RECOVERABLE(nomad->stream.error)) {
  500.                         d_print("unrecoverable frame level error.\n");
  501.                         return -1;
  502.                 }
  503.                 if (nomad->stream.error == MAD_ERROR_LOSTSYNC)
  504.                         handle_lost_sync(nomad);
  505.                 goto start;
  506.         }
  507.         nomad->cur_frame++;
  508.         nomad->current.bitrate_sum += nomad->frame.header.bitrate;
  509.         nomad->current.nr_frames++;
  510.         if (nomad->info.filesize != -1) {
  511.                 build_seek_index(nomad);
  512.         } else {
  513.                 mad_timer_add(&nomad->timer, nomad->frame.header.duration);
  514.         }
  515.         mad_synth_frame(&nomad->synth, &nomad->frame);
  516.         return 0;
  517. }
  518.  
  519. static void init_mad(struct nomad *nomad)
  520. {
  521.         mad_stream_init(&nomad->stream);
  522.         nomad->stream.options |= MAD_OPTION_IGNORECRC;
  523.         mad_frame_init(&nomad->frame);
  524.         mad_synth_init(&nomad->synth);
  525.         mad_timer_reset(&nomad->timer);
  526.         nomad->cur_frame = 0;
  527.         nomad->i = -1;
  528.         nomad->input_offset = 0;
  529.         nomad->seen_first_frame = 0;
  530.         nomad->readEOF = 0;
  531. }
  532.  
  533. static void free_mad(struct nomad *nomad)
  534. {
  535.         mad_stream_finish(&nomad->stream);
  536.         mad_frame_finish(&nomad->frame);
  537.         mad_synth_finish(nomad->synth);
  538. }
  539.  
  540. static int do_open(struct nomad *nomad)
  541. {
  542.         int rc;
  543.  
  544.         init_mad(nomad);
  545.         nomad->info.filesize = nomad->cbs.lseek(nomad->datasource, 0, SEEK_END);
  546.         if (nomad->info.filesize != -1)
  547.                 nomad->cbs.lseek(nomad->datasource, 0, SEEK_SET);
  548.         if (nomad->info.filesize == -1) {
  549.                 rc = decode(nomad);
  550.                 if (rc < 0)
  551.                         goto error;
  552.                 if (rc == 1)
  553.                         goto eof;
  554.                 nomad->info.sample_rate = nomad->frame.header.samplerate;
  555.                 nomad->info.channels = MAD_NCHANNELS(&nomad->frame.header);
  556.                 nomad->info.layer = nomad->frame.header.layer;
  557.                 nomad->info.dual_channel = nomad->frame.header.mode == MAD_MODE_DUAL_CHANNEL;
  558.                 nomad->info.joint_stereo = nomad->frame.header.mode == MAD_MODE_JOINT_STEREO;
  559.  
  560.                 /* unknown */
  561.                 nomad->info.duration = -1.0;
  562.                 nomad->info.nr_frames = -1;
  563.                 nomad->info.vbr = -1;
  564.                 nomad->info.avg_bitrate = -1;
  565.         } else {
  566.                 rc = scan(nomad);
  567.                 if (rc < 0)
  568.                         goto error;
  569.                 if (rc == 1)
  570.                         goto eof;
  571.                 free_mad(nomad);
  572.                 init_mad(nomad);
  573.         }
  574.         d_print("\n  frames: %d, br: %d b/s, sr: %d Hz, ch: %d, layer: %d, joint stereo: %d\n"
  575.                 "  dual channel: %d, vbr: %d, duration: %g s, xing: %d\n",
  576.                         nomad->info.nr_frames, nomad->info.avg_bitrate,
  577.                         nomad->info.sample_rate, nomad->info.channels,
  578.                         nomad->info.layer, nomad->info.joint_stereo,
  579.                         nomad->info.dual_channel, nomad->info.vbr,
  580.                         nomad->info.duration,
  581.                         nomad->has_xing);
  582. #if defined(DEBUG_XING)
  583.         if (nomad->has_xing)
  584.                 d_print("xing: flags: 0x%x, frames: %d, bytes: %d, scale: %d\n",
  585.                         nomad->xing.flags,
  586.                         nomad->xing.nr_frames,
  587.                         nomad->xing.bytes,
  588.                         nomad->xing.scale);
  589. #endif
  590.         return 0;
  591. error:
  592.         nomad_close(nomad);
  593.         return rc;
  594. eof:
  595.         nomad_close(nomad);
  596.         return -NOMAD_ERROR_FILE_FORMAT;
  597. }
  598.  
  599. int nomad_open_callbacks(struct nomad **nomadp, void *datasource, struct nomad_callbacks *cbs)
  600. {
  601.         struct nomad *nomad;
  602.  
  603.         const struct nomad nomad_init = {
  604.                 .datasource = datasource,
  605.                 .cbs = {
  606.                         .read  = cbs->read,
  607.                         .lseek = cbs->lseek,
  608.                         .close = cbs->close
  609.                 }
  610.         };
  611.  
  612.         nomad = xnew(struct nomad, 1);
  613.         *nomad = nomad_init;
  614.         nomad->lame.peak = nomad->lame.trackGain = nomad->lame.albumGain = strtof("NAN", NULL);
  615.         *nomadp = nomad;
  616.         /* on error do_open calls nomad_close */
  617.         return do_open(nomad);
  618. }
  619.  
  620. void nomad_close(struct nomad *nomad)
  621. {
  622.         free_mad(nomad);
  623.         nomad->cbs.close(nomad->datasource);
  624.         free(nomad->seek_idx.table);
  625.         free(nomad);
  626. }
  627.  
  628. int nomad_read(struct nomad *nomad, char *buffer, int count)
  629. {
  630.         int i, j, size, psize, to;
  631.  
  632.         if (nomad->i == -1) {
  633.                 int rc;
  634.  
  635. next_frame:
  636.                 rc = decode(nomad);
  637.                 if (rc < 0)
  638.                         return rc;
  639.                 if (rc == 1)
  640.                         return 0;
  641.                 nomad->i = 0;
  642.         }
  643.  
  644.         if (nomad->has_lame) {
  645.                 /* skip samples at start for gapless playback */
  646.                 if (nomad->start_drop_frames) {
  647.                         nomad->start_drop_frames--;
  648.                         /* XING header is an empty frame we want to skip */
  649.                         if (!nomad->seen_first_frame) {
  650.                                 nomad->cur_frame--;
  651.                                 nomad->seen_first_frame = 1;
  652.                         }
  653. #if defined(DEBUG_LAME)
  654.                         d_print("skipped a frame at start\n");
  655. #endif
  656.                         goto next_frame;
  657.                 }
  658.                 if (nomad->start_drop_samples) {
  659.                         if (nomad->start_drop_samples < nomad->synth.pcm.length) {
  660.                                 nomad->i += nomad->start_drop_samples;
  661.                                 nomad->start_drop_samples = 0;
  662.                                 /* Take advantage of the fact that this block is only executed once per file, and
  663.                                    calculate the # of samples/frames to skip at the end.  Note that synth.pcm.length
  664.                                    is needed for the calculation. */
  665.                                 nomad->end_drop_frames = nomad->end_drop_samples / nomad->synth.pcm.length;
  666.                                 nomad->end_drop_samples = nomad->end_drop_samples % nomad->synth.pcm.length;
  667. #if defined(DEBUG_LAME)
  668.                                 d_print("skipped %d samples at start\n", nomad->i);
  669.                                 d_print("will skip %d samples and %d frame(s) at end\n",
  670.                                         nomad->end_drop_samples, nomad->end_drop_frames);
  671. #endif
  672.                         }
  673.                         else {
  674.                                 nomad->start_drop_samples -= nomad->synth.pcm.length;
  675. #if defined(DEBUG_LAME)
  676.                                 d_print("skipped %d samples at start and moving to next frame\n", nomad->synth.pcm.length);
  677. #endif
  678.                                 goto next_frame;
  679.                         }
  680.                 }
  681.                 /* skip samples/frames at end for gapless playback */
  682.                 if (nomad->cur_frame == (nomad->xing.nr_frames + 1 - nomad->end_drop_frames)) {
  683. #if defined(DEBUG_LAME)
  684.                                 d_print("skipped %d frame(s) at end\n", nomad->end_drop_frames);
  685. #endif
  686.                         return 0;
  687.                 }
  688.         }
  689.  
  690.         psize = nomad->info.channels * 16 / 8;
  691.         size = (nomad->synth.pcm.length - nomad->i) * psize;
  692.  
  693.         if (size > count) {
  694.                 to = nomad->i + count / psize;
  695.         } else {
  696.                 to = nomad->synth.pcm.length;
  697.         }
  698.         j = 0;
  699.         for (i = nomad->i; i < to; i++) {
  700.                 short sample;
  701.  
  702.                 /* skip samples/frames at end for gapless playback */
  703.                 if (nomad->has_lame
  704.                     && nomad->end_drop_samples
  705.                     && (nomad->cur_frame == (nomad->xing.nr_frames - nomad->end_drop_frames))
  706.                     && i == (nomad->synth.pcm.length - nomad->end_drop_samples)) {
  707.                         nomad->i = -1;
  708. #if defined(DEBUG_LAME)
  709.                         d_print("skipped %d samples at end of frame %d\n", nomad->end_drop_samples, (int)nomad->cur_frame);
  710. #endif
  711.                         return j;
  712.                 }
  713.                 sample = scale(nomad->synth.pcm.samples[0][i]);
  714.                 buffer[j++] = (sample >> 0) & 0xff;
  715.                 buffer[j++] = (sample >> 8) & 0xff;
  716.  
  717.                 if (nomad->info.channels == 2) {
  718.                         sample = scale(nomad->synth.pcm.samples[1][i]);
  719.                         buffer[j++] = (sample >> 0) & 0xff;
  720.                         buffer[j++] = (sample >> 8) & 0xff;
  721.                 }
  722.         }
  723.         if (to != nomad->synth.pcm.length) {
  724.                 nomad->i = i;
  725.         } else {
  726.                 nomad->i = -1;
  727.         }
  728.         return j;
  729. }
  730.  
  731. static int nomad_time_seek_accurate(struct nomad *nomad, double pos)
  732. {
  733.         int rc;
  734.  
  735.         /* seek to beginning of file and search frame-by-frame */
  736.         if (nomad->cbs.lseek(nomad->datasource, 0, SEEK_SET) == -1)
  737.                 return -1;
  738.  
  739.         /* XING header should NOT be counted - if we're here, we know it's present */
  740.         nomad->cur_frame = -1;
  741.  
  742.         while (timer_to_seconds(nomad->timer) < pos) {
  743.                 rc = fill_buffer(nomad);
  744.                 if (rc == -1)
  745.                         return -1;
  746.                 if (rc == 0)
  747.                         return 1;
  748.  
  749.                 if (mad_header_decode(&nomad->frame.header, &nomad->stream)) {
  750.                         if (nomad->stream.error == MAD_ERROR_BUFLEN)
  751.                                 continue;
  752.                         if (!MAD_RECOVERABLE(nomad->stream.error)) {
  753.                                 d_print("unrecoverable frame level error.\n");
  754.                                 return -1;
  755.                         }
  756.                         if (nomad->stream.error == MAD_ERROR_LOSTSYNC)
  757.                                 handle_lost_sync(nomad);
  758.                         continue;
  759.                 }
  760.                 nomad->cur_frame++;
  761.                 mad_timer_add(&nomad->timer, nomad->frame.header.duration);
  762.         }
  763. #if defined(DEBUG_LAME)
  764.                 d_print("seeked to %g = %g\n", pos, timer_to_seconds(nomad->timer));
  765. #endif
  766.         return 0;
  767. }
  768.  
  769. int nomad_time_seek(struct nomad *nomad, double pos)
  770. {
  771.         off_t offset = 0;
  772.  
  773.         if (pos < 0.0 || pos > nomad->info.duration) {
  774.                 errno = EINVAL;
  775.                 return -1;
  776.         }
  777.         if (nomad->info.filesize == -1) {
  778.                 errno = ESPIPE;
  779.                 return -1;
  780.         }
  781.         free_mad(nomad);
  782.         init_mad(nomad);
  783.  
  784.         /* if file has a LAME header, perform frame-accurate seek for gapless playback */
  785.         if (nomad->has_lame) {
  786.                 return nomad_time_seek_accurate(nomad, pos);
  787.         } else if (nomad->has_xing) {
  788.                 /* calculate seek offset */
  789.                 /* seek to truncate(pos / duration * 100) / 100 * duration */
  790.                 double k, tmp_pos;
  791.                 int ki;
  792.  
  793.                 k = pos / nomad->info.duration * 100.0;
  794.                 ki = k;
  795.                 tmp_pos = ((double)ki) / 100.0 * nomad->info.duration;
  796.                 nomad->timer.seconds = (signed int)tmp_pos;
  797.                 nomad->timer.fraction = (tmp_pos - (double)nomad->timer.seconds) * MAD_TIMER_RESOLUTION;
  798. #if defined(DEBUG_XING)
  799.                 d_print("seeking to %g = %g %d%%\n",
  800.                                 pos,
  801.                                 timer_to_seconds(nomad->timer),
  802.                                 ki);
  803. #endif
  804.                 offset = ((unsigned long long)nomad->xing.toc[ki] * nomad->xing.bytes) / 256;
  805.         } else if (nomad->seek_idx.size > 0) {
  806.                 int idx = (int)(pos / SEEK_IDX_INTERVAL) - 1;
  807.  
  808.                 if (idx > nomad->seek_idx.size - 1)
  809.                         idx = nomad->seek_idx.size - 1;
  810.  
  811.                 if (idx >= 0) {
  812.                         offset = nomad->seek_idx.table[idx].offset;
  813.                         nomad->timer = nomad->seek_idx.table[idx].timer;
  814.                 }
  815.         }
  816.         if (nomad->cbs.lseek(nomad->datasource, offset, SEEK_SET) == -1)
  817.                 return -1;
  818.  
  819.         nomad->input_offset = offset;
  820.         while (timer_to_seconds(nomad->timer) < pos) {
  821.                 int rc;
  822.  
  823.                 rc = fill_buffer(nomad);
  824.                 if (rc == -1)
  825.                         return -1;
  826.                 if (rc == 0)
  827.                         return 0;
  828.  
  829.                 if (mad_header_decode(&nomad->frame.header, &nomad->stream) == 0) {
  830.                         build_seek_index(nomad);
  831.                 } else {
  832.                         if (!MAD_RECOVERABLE(nomad->stream.error) && nomad->stream.error != MAD_ERROR_BUFLEN) {
  833.                                 d_print("unrecoverable frame level error.\n");
  834.                                 return -1;
  835.                         }
  836.                         if (nomad->stream.error == MAD_ERROR_LOSTSYNC)
  837.                                 handle_lost_sync(nomad);
  838.                 }
  839.         }
  840. #if defined(DEBUG_XING)
  841.         if (nomad->has_xing)
  842.                 d_print("seeked to %g = %g\n", pos, timer_to_seconds(nomad->timer));
  843. #endif
  844.         return 0;
  845. }
  846.  
  847. const struct nomad_xing *nomad_xing(struct nomad *nomad)
  848. {
  849.         return nomad->has_xing ? &nomad->xing : NULL;
  850. }
  851.  
  852. const struct nomad_lame *nomad_lame(struct nomad *nomad)
  853. {
  854.         return nomad->has_lame ? &nomad->lame : NULL;
  855. }
  856.  
  857. const struct nomad_info *nomad_info(struct nomad *nomad)
  858. {
  859.         return &nomad->info;
  860. }
  861.  
  862. long nomad_current_bitrate(struct nomad *nomad)
  863. {
  864.         long bitrate = -1;
  865.         if (nomad->current.nr_frames > 0) {
  866.                 bitrate = nomad->current.bitrate_sum / nomad->current.nr_frames;
  867.                 nomad->current.bitrate_sum = 0;
  868.                 nomad->current.nr_frames = 0;
  869.         }
  870.         return bitrate;
  871. }
  872.  
downloadnomad.c Source code - Download cmus Source code
Related Source Codes/Software:
Ink - An HTML5/CSS3 framework used at SAPO for fast and ... 2017-04-22
memory-stats.js - minimal monitor for JS Heap Size via performance.m... 2017-04-22
LayoutKit - LayoutKit is a fast view layout library for iOS, m... 2017-04-22
Cpp-Primer - C++ Primer 5 answer 2017-04-22
RBBAnimation - Block-based animations made easy, comes with easin... 2017-04-22
phpDocumentor2 - Documentation Generator for PHP ... 2017-04-22
flexboxfroggy - A game for learning CSS flexbox ... 2017-04-22
wicked - Use wicked to turn your controller into a wizard ... 2017-04-22
Begin-Latex-in-minutes - Brief Intro to LaTeX for beginners that helps you ... 2017-04-22
guard-livereload - Guard::LiveReload automatically reload your browse... 2017-04-22
swifter - Tiny http server engine written in Swift programmi... 2017-04-29
Chartbuilder - A front-end charting application that facilitates ... 2017-04-29
offline-first - 2017-04-29
plotly.py - An interactive, browser-based graphing library for... 2017-04-29
statsmodels - Statsmodels: statistical modeling and econometrics... 2017-04-29
android-maps-utils - Handy extensions to the Google Maps Android API. 2017-04-29
enyo - A JavaScript application framework emphasizing mod... 2017-04-29
darkforestGo - DarkForest, the Facebook Go engine. 2017-04-29
erpnext - ERP made Simple http://erpn... 2017-04-29
SwiftInFlux - An attempt to gather all that is in flux in Swift. 2017-04-29

 Back to top