Exemple #1
0
int cdd_context_load(uint8 *state)
{
  int lba;
  int bufferptr = 0;

#ifdef USE_LIBTREMOR
#ifdef DISABLE_MANY_OGG_OPEN_FILES
  /* close previous track VORBIS file structure to save memory */
  if (cdd.toc.tracks[cdd.index].vf.datasource)
  {
    ogg_free(cdd.index);
  }
#endif
#endif

  load_param(&cdd.cycles, sizeof(cdd.cycles));
  load_param(&cdd.latency, sizeof(cdd.latency));
  load_param(&cdd.index, sizeof(cdd.index));
  load_param(&cdd.lba, sizeof(cdd.lba));
  load_param(&cdd.scanOffset, sizeof(cdd.scanOffset));
  load_param(&cdd.volume, sizeof(cdd.volume));
  load_param(&cdd.status, sizeof(cdd.status));

  /* adjust current LBA within track limit */
  lba = cdd.lba;
  if (lba < cdd.toc.tracks[cdd.index].start)
  {
    lba = cdd.toc.tracks[cdd.index].start;
  }

  /* seek to current track position */
  if (!cdd.index)
  {
    /* DATA track */
    if (cdd.toc.tracks[0].fd)
    {
      pm_seek(cdd.toc.tracks[0].fd, lba * cdd.sectorSize, SEEK_SET);
    }
  }
#ifdef USE_LIBTREMOR
  else if (cdd.toc.tracks[cdd.index].vf.seekable)
  {
#ifdef DISABLE_MANY_OGG_OPEN_FILES
    /* VORBIS file need to be opened first */
    ov_open(cdd.toc.tracks[cdd.index].fd,&cdd.toc.tracks[cdd.index].vf,0,0);
#endif
    /* VORBIS AUDIO track */
    ov_pcm_seek(&cdd.toc.tracks[cdd.index].vf, (lba - cdd.toc.tracks[cdd.index].start) * 588 - cdd.toc.tracks[cdd.index].offset);
  }
#endif
#if 0
  else if (cdd.toc.tracks[cdd.index].fd)
  {
    /* PCM AUDIO track */
    fseek(cdd.toc.tracks[cdd.index].fd, (lba * 2352) - cdd.toc.tracks[cdd.index].offset, SEEK_SET);
  }
#else
  else
  {
    cdd_change_track(cdd.index, lba);
  }
#endif

  return bufferptr;
}
Exemple #2
0
/* this is the codec entry point */
enum codec_status codec_main(void)
{
    ov_callbacks callbacks;
    OggVorbis_File vf;
    ogg_int32_t **pcm;

    int error;
    long n;
    int current_section;
    int previous_section;
    int eof;
    ogg_int64_t vf_offsets[2];
    ogg_int64_t vf_dataoffsets;
    ogg_uint32_t vf_serialnos;
    ogg_int64_t vf_pcmlengths[2];

    ci->configure(DSP_SET_SAMPLE_DEPTH, 24);

    if (codec_init()) {
        error = CODEC_ERROR;
        goto exit;
    }

    ogg_malloc_init();

#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS)
    if (setjmp(rb_jump_buf) != 0) {
        /* malloc failed; skip to next track */
        error = CODEC_ERROR;
        goto done;
    }
#endif

next_track:
    while (!*ci->taginfo_ready && !ci->stop_codec)
        ci->sleep(1);

    /* Create a decoder instance */
    callbacks.read_func = read_handler;
    callbacks.seek_func = initial_seek_handler;
    callbacks.tell_func = tell_handler;
    callbacks.close_func = close_handler;

    /* Open a non-seekable stream */
    error = ov_open_callbacks(ci, &vf, NULL, 0, callbacks);
    
    /* If the non-seekable open was successful, we need to supply the missing
     * data to make it seekable.  This is a hack, but it's reasonable since we
     * don't want to run the whole file through the buffer before we start
     * playing.  Using Tremor's seekable open routine would cause us to do
     * this, so we pretend not to be seekable at first.  Then we fill in the
     * missing fields of vf with 1) information in ci->id3, and 2) info
     * obtained by Tremor in the above ov_open call.
     *
     * Note that this assumes there is only ONE logical Vorbis bitstream in our
     * physical Ogg bitstream.  This is verified in metadata.c, well before we
     * get here.
     */
    if (!error) {
         ogg_free(vf.offsets);
         ogg_free(vf.dataoffsets);
         ogg_free(vf.serialnos);

         vf.offsets = vf_offsets;
         vf.dataoffsets = &vf_dataoffsets;
         vf.serialnos = &vf_serialnos;
         vf.pcmlengths = vf_pcmlengths;

         vf.offsets[0] = 0;
         vf.offsets[1] = ci->id3->filesize;
         vf.dataoffsets[0] = vf.offset;
         vf.pcmlengths[0] = 0;
         vf.pcmlengths[1] = ci->id3->samples;
         vf.serialnos[0] = vf.current_serialno;
         vf.callbacks.seek_func = seek_handler;
         vf.seekable = 1;
         vf.end = ci->id3->filesize;
         vf.ready_state = OPENED;
         vf.links = 1;
    } else {
         DEBUGF("Vorbis: ov_open failed: %d", error);
         error = CODEC_ERROR;
         goto done;
    }

    if (ci->id3->offset) {
        ci->advance_buffer(ci->id3->offset);
        ov_raw_seek(&vf, ci->id3->offset);
        ci->set_elapsed(ov_time_tell(&vf));
        ci->set_offset(ov_raw_tell(&vf));
    }

    previous_section = -1;
    eof = 0;
    while (!eof) {
        ci->yield();
        if (ci->stop_codec || ci->new_track)
            break;

        if (ci->seek_time) {
            if (ov_time_seek(&vf, ci->seek_time - 1)) {
                //ci->logf("ov_time_seek failed");
            }
            ci->seek_complete();
        }

        /* Read host-endian signed 24-bit PCM samples */
        n = ov_read_fixed(&vf, &pcm, 1024, &current_section);

        /* Change DSP and buffer settings for this bitstream */
        if (current_section != previous_section) {
            if (!vorbis_set_codec_parameters(&vf)) {
                error = CODEC_ERROR;
                goto done;
            } else {
                previous_section = current_section;
            }
        }

        if (n == 0) {
            eof = 1;
        } else if (n < 0) {
            DEBUGF("Vorbis: Error decoding frame\n");
        } else {
            ci->pcmbuf_insert(pcm[0], pcm[1], n);
            ci->set_offset(ov_raw_tell(&vf));
            ci->set_elapsed(ov_time_tell(&vf));
        }
    }
    error = CODEC_OK;
    
done:
#if 0 /* defined(SIMULATOR) */
    {
        size_t bufsize;
        void* buf = ci->codec_get_buffer(&bufsize);

        DEBUGF("Vorbis: Memory max: %u\n", get_max_size(buf));
    }
#endif

    if (ci->request_next_track()) {
        /* Clean things up for the next track */
        vf.dataoffsets = NULL;
        vf.offsets = NULL;
        vf.serialnos = NULL;
        vf.pcmlengths = NULL;
        ov_clear(&vf);
        goto next_track;
    }
        
exit:
    ogg_malloc_destroy();
    return error;
}