Example #1
0
File: mmf.c Project: Arcen/libav
/* mmf input */
static int mmf_read_header(AVFormatContext *s)
{
    MMFContext *mmf = s->priv_data;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    AVStream *st;
    int64_t size;
    int rate, params;

    tag = avio_rl32(pb);
    if (tag != MKTAG('M', 'M', 'M', 'D'))
        return -1;
    avio_skip(pb, 4); /* file_size */

    /* Skip some unused chunks that may or may not be present */
    for(;; avio_skip(pb, size)) {
        tag = avio_rl32(pb);
        size = avio_rb32(pb);
        if(tag == MKTAG('C','N','T','I')) continue;
        if(tag == MKTAG('O','P','D','A')) continue;
        break;
    }

    /* Tag = "ATRx", where "x" = track number */
    if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n");
        return -1;
    }
    if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag);
        return -1;
    }

    avio_r8(pb); /* format type */
    avio_r8(pb); /* sequence type */
    params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */
    rate = mmf_rate(params & 0x0f);
    if(rate  < 0) {
        av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
        return -1;
    }
    avio_r8(pb); /* wave base bit */
    avio_r8(pb); /* time base d */
    avio_r8(pb); /* time base g */

    /* Skip some unused chunks that may or may not be present */
    for(;; avio_skip(pb, size)) {
        tag = avio_rl32(pb);
        size = avio_rb32(pb);
        if(tag == MKTAG('A','t','s','q')) continue;
        if(tag == MKTAG('A','s','p','I')) continue;
        break;
    }

    /* Make sure it's followed by an Awa chunk, aka wave data */
    if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) {
        av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag);
        return -1;
    }
    mmf->data_size = size;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA;
    st->codec->sample_rate = rate;
    st->codec->channels = 1;
    st->codec->bits_per_coded_sample = 4;
    st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;

    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    return 0;
}
Example #2
0
static int open_smaf(bgav_demuxer_context_t * ctx)
  {
  int done = 0;
  uint8_t params;
  chunk_header_t ch;
  bgav_stream_t * s;

  smaf_priv_t * priv;
  priv = calloc(1, sizeof(*priv));
  ctx->priv = priv;

  /* Skip MMMD chunk */
  bgav_input_skip(ctx->input, 8);

  while(!done)
    {
    if(!read_chunk_header(ctx->input, &ch))
      return 0;

    //    dump_chunk_header(&ch);

    if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('M','T','R',0))
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "MIDI like files not supported");
      return 0;
      }

    else if((ch.fourcc == BGAV_MK_FOURCC('C','N','T','I')) ||
            (ch.fourcc == BGAV_MK_FOURCC('O','P','D','A')))
      bgav_input_skip(ctx->input, ch.size);

    else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','T','R',0))
      done = 1;

    else
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "Unsupported SMAF chunk (%c%c%c%c)",
               (ch.fourcc & 0xFF000000) >> 24,
               (ch.fourcc & 0x00FF0000) >> 16,
               (ch.fourcc & 0x0000FF00) >> 8,
               (ch.fourcc & 0x000000FF));
      return 0;
      }
    
    }

  /* Initialize generic things */

  ctx->tt = bgav_track_table_create(1);
  s = bgav_track_add_audio_stream(ctx->tt->cur, ctx->opt);
  
  /* Now, get the format */
   
  bgav_input_skip(ctx->input, 1); /* format type */
  bgav_input_skip(ctx->input, 1); /* sequence type */

  /* (channel << 7) | (format << 4) | rate */
  if(!bgav_input_read_data(ctx->input, &params, 1)) 
    return 0;
  
  s->data.audio.format.samplerate = mmf_rate(params & 0x0f);
  s->fourcc = BGAV_MK_FOURCC('S','M','A','F');
  s->data.audio.bits_per_sample = 4;
  s->data.audio.format.num_channels = 1;
  s->data.audio.bits_per_sample = 4;
  s->container_bitrate = s->data.audio.bits_per_sample *
    s->data.audio.format.samplerate;
    
  if(s->data.audio.format.samplerate < 0)
    {
    bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
             "Invalid samplerate");
    return 0;
    }
  bgav_input_skip(ctx->input, 1); /* wave base bit */
  bgav_input_skip(ctx->input, 1); /* time base d   */
  bgav_input_skip(ctx->input, 1); /* time base g   */

  done = 0;
  while(!done)
    {
    if(!read_chunk_header(ctx->input, &ch))
      return 0;

    //    dump_chunk_header(&ch);

    if((ch.fourcc == BGAV_MK_FOURCC('A','t','s','q')) ||
       (ch.fourcc == BGAV_MK_FOURCC('A','s','p','I')))
      bgav_input_skip(ctx->input, ch.size);

    else if((ch.fourcc & 0xffffff00) == BGAV_MK_FOURCC('A','w','a', 0))
      done = 1;

    else
      {
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "Unsupported SMAF chunk (%c%c%c%c)",
               (ch.fourcc & 0xFF000000) >> 24,
               (ch.fourcc & 0x00FF0000) >> 16,
               (ch.fourcc & 0x0000FF00) >> 8,
               (ch.fourcc & 0x000000FF));
      return 0;
      }
    }
  priv->bytes_left = ch.size;

  gavl_metadata_set(&ctx->tt->cur->metadata, 
                    GAVL_META_FORMAT, "SMAF Ringtone");

  return 1;
  }