Exemplo n.º 1
0
/* Function: al_load_ogg_vorbis_audio_stream_f
 */
ALLEGRO_AUDIO_STREAM *al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE* file,
	size_t buffer_count, unsigned int samples)
{
   const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */
   OggVorbis_File* vf;
   vorbis_info* vi;
   int channels;
   long rate;
   long total_samples;
   long total_size;
   AL_OV_DATA* extra;
   ALLEGRO_AUDIO_STREAM* stream;

   extra = _AL_MALLOC(sizeof(AL_OV_DATA));
   if (extra == NULL) {
      ALLEGRO_ERROR("Failed to allocate AL_OV_DATA struct.\n");
      return NULL;
   }
   
   if (file == NULL) {
      ALLEGRO_WARN("File failed to open\n");
      fprintf(stderr, "File failed to open\n");
      return NULL;
   }
   
   extra->file = file;
   
   vf = _AL_MALLOC(sizeof(OggVorbis_File));
   if (ov_open_callbacks(extra, vf, NULL, 0, callbacks) < 0) {
      ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n");
      al_fclose(file);
      return NULL;
   }

   extra->vf = vf;

   vi = ov_info(vf, -1);
   channels = vi->channels;
   rate = vi->rate;
   total_samples = ov_pcm_total(vf,-1);
   total_size = total_samples * channels * word_size;

   extra->vi = vi;

   extra->bitstream = -1;

   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", total_size);
	
   stream = al_create_audio_stream(buffer_count, samples, rate,
            _al_word_size_to_depth_conf(word_size),
            _al_count_to_channel_conf(channels));
   if (!stream) {
      free(vf);
      return NULL;
   }

   stream->extra = extra;

   extra->loop_start = 0.0;
   extra->loop_end = ogg_stream_get_length(stream);
   stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream);
   stream->quit_feed_thread = false;
   stream->feeder = ogg_stream_update;
   stream->rewind_feeder = ogg_stream_rewind;
   stream->seek_feeder = ogg_stream_seek;
   stream->get_feeder_position = ogg_stream_get_position;
   stream->get_feeder_length = ogg_stream_get_length;
   stream->set_feeder_loop = ogg_stream_set_loop;
   stream->unload_feeder = ogg_stream_close;
   al_start_thread(stream->feed_thread);
	
   return stream;
}
Exemplo n.º 2
0
/* Function: al_load_ogg_vorbis_f
 */
ALLEGRO_SAMPLE *al_load_ogg_vorbis_f(ALLEGRO_FILE* file)
{
   /* Note: decoding library returns floats.  I always return 16-bit (most
    * commonly supported).
    */
#ifdef ALLEGRO_LITTLE_ENDIAN
   const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */
#else
   const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */
#endif
   int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */
   int signedness = 1; /* 0  for unsigned, 1 for signed */
   const int packet_size = 4096; /* suggestion for size to read at a time */
   OggVorbis_File vf;
   vorbis_info* vi;
   char *buffer;
   long pos;
   ALLEGRO_SAMPLE *sample;
   int channels;
   long rate;
   long total_samples;
   int bitstream;
   long total_size;
   AL_OV_DATA ov;

   if (file == NULL) {
      ALLEGRO_WARN("Audio file failed to open.\n");
      return NULL;
   }
   ov.file = file;
   if (ov_open_callbacks(&ov, &vf, NULL, 0, callbacks) < 0) {
      ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n");
      al_fclose(file);
      return NULL;
   }

   vi = ov_info(&vf, -1);

   channels = vi->channels;
   rate = vi->rate;
   total_samples = ov_pcm_total(&vf, -1);
   bitstream = -1;
   total_size = total_samples * channels * word_size;

   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", total_size);

   buffer = _AL_MALLOC_ATOMIC(total_size);
   if (!buffer) {
      al_fclose(file);
      return NULL;
   }

   pos = 0;
   while (pos < total_size) {
      /* XXX error handling */
#if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE)
      long read = ov_read(&vf, buffer + pos, packet_size, endian, word_size,
         signedness, &bitstream);
#else
      (void)endian;
      (void)signedness;
      long read = ov_read(&vf, buffer + pos, packet_size, &bitstream);
#endif
      pos += read;
      if (read == 0)
         break;
   }

   ov_clear(&vf);

   sample = al_create_sample(buffer, total_samples, rate,
      _al_word_size_to_depth_conf(word_size),
      _al_count_to_channel_conf(channels), true);

   if (!sample) {
      _AL_FREE(buffer);
   }

   return sample;
}
Exemplo n.º 3
0
ALLEGRO_SAMPLE *_al_load_ogg_opus_f(ALLEGRO_FILE *file)
{
   /* Note: decoding library can return 16-bit or floating-point output,
    * both using native endian ordering. (TODO: Implement float output,
    * individual links in the stream...)
    */
   int word_size = 2; /* 2 = 16-bit. */
   const int packet_size = 5760; /* suggestion for size to read at a time */
   OggOpusFile *of;
   opus_int16 *buffer;
   ALLEGRO_SAMPLE *sample;
   int channels;
   long rate;
   ogg_int64_t total_samples;
   int bitstream;
   ogg_int64_t total_size;
   AL_OP_DATA op;
   ogg_int64_t pos;
   long read;

   if (!init_dynlib()) {
      return NULL;
   }

   op.file = file;
   of = lib.op_open_callbacks(&op, &callbacks, NULL, 0, NULL);
   if (!of) {
      ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n");
      return NULL;
   }

   bitstream = -1;
   channels = lib.op_channel_count(of, bitstream);
   rate = 48000;
   total_samples = lib.op_pcm_total(of, bitstream);
   total_size = total_samples * channels * word_size;

   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", (long)total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", (long)total_size);

   buffer = al_malloc(total_size);
   if (!buffer) {
      return NULL;
   }

   pos = 0;
   while (pos < total_samples) {
      const int read_size = _ALLEGRO_MIN(packet_size, total_samples - pos);
      ASSERT(pos + read_size <= total_samples);

      /* XXX error handling */
      read = lib.op_read(of, buffer + pos * channels, read_size, NULL);

      pos += read;
      if (read == 0)
         break;
   }

   lib.op_free(of);

   sample = al_create_sample(buffer, total_samples, rate,
      _al_word_size_to_depth_conf(word_size),
      _al_count_to_channel_conf(channels), true);

   if (!sample) {
      al_free(buffer);
   }

   return sample;
}
Exemplo n.º 4
0
ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream_f(ALLEGRO_FILE *file,
   size_t buffer_count, unsigned int samples)
{
   const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */
   OggOpusFile* of;
   int channels;
   long rate;
   long total_samples;
   long total_size;
   int bitstream;
   AL_OP_DATA* extra;
   ALLEGRO_AUDIO_STREAM* stream;

   if (!init_dynlib()) {
      return NULL;
   }

   extra = al_malloc(sizeof(AL_OP_DATA));
   if (extra == NULL) {
      ALLEGRO_ERROR("Failed to allocate AL_OP_DATA struct.\n");
      return NULL;
   }

   extra->file = file;

   of = lib.op_open_callbacks(extra, &callbacks, NULL, 0, NULL);
   if (!of) {
      ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n");
      return NULL;
   }

   extra->of = of;
   extra->bitstream = -1;
   bitstream = extra->bitstream;

   extra->channels = lib.op_channel_count(of, bitstream);
   channels = extra->channels;

   rate = 48000;
   total_samples = lib.op_pcm_total(of, bitstream);
   total_size = total_samples * channels * word_size;


   ALLEGRO_DEBUG("channels %d\n", channels);
   ALLEGRO_DEBUG("word_size %d\n", word_size);
   ALLEGRO_DEBUG("rate %ld\n", rate);
   ALLEGRO_DEBUG("total_samples %ld\n", total_samples);
   ALLEGRO_DEBUG("total_size %ld\n", total_size);

   stream = al_create_audio_stream(buffer_count, samples, rate,
            _al_word_size_to_depth_conf(word_size),
            _al_count_to_channel_conf(channels));
   if (!stream) {
      lib.op_free(of);
      return NULL;
   }

   stream->extra = extra;

   extra->loop_start = 0.0;
   extra->loop_end = ogg_stream_get_length(stream);
   stream->quit_feed_thread = false;
   stream->feeder = ogg_stream_update;
   stream->rewind_feeder = ogg_stream_rewind;
   stream->seek_feeder = ogg_stream_seek;
   stream->get_feeder_position = ogg_stream_get_position;
   stream->get_feeder_length = ogg_stream_get_length;
   stream->set_feeder_loop = ogg_stream_set_loop;
   stream->unload_feeder = ogg_stream_close;
   _al_acodec_start_feed_thread(stream);

   return stream;
}
Exemplo n.º 5
0
ALLEGRO_SAMPLE *_al_load_voc_f(ALLEGRO_FILE *file)
{
   AL_VOC_DATA *vocdata;
   ALLEGRO_SAMPLE *sample = NULL;
   size_t pos = 0; /* where to write in the buffer */
   size_t read = 0; /*bytes read during last operation */
   char* buffer;

   size_t bytestoread = 0;
   bool endofvoc = false;

   vocdata = al_malloc(sizeof(AL_VOC_DATA));
   memset(vocdata, 0, sizeof(*vocdata));
   /*
    * Open file and populate VOC DATA, then create a buffer for the number of
    * samples of the frst block.
    * Iterate on the following blocks till EOF or terminator block
    */
   vocdata = voc_open(file);
   if (!vocdata) return NULL;

   ALLEGRO_DEBUG("channels %d\n", vocdata->channels);
   ALLEGRO_DEBUG("word_size %d\n", vocdata->sample_size);
   ALLEGRO_DEBUG("rate %d\n", vocdata->samplerate);
   ALLEGRO_DEBUG("first_block_samples %d\n", vocdata->samples);
   ALLEGRO_DEBUG("first_block_size %d\n", vocdata->samples * vocdata->sample_size);

   /*
    * Let's allocate at least the first block's bytes;
    */
   buffer = al_malloc(vocdata->samples * vocdata->sample_size);
   if (!buffer) {
      return NULL;
   }
   /*
    * We now need to iterate over data blocks till either we hit end of file
    * or we find a terminator block.
    */
   bytestoread = vocdata->samples * vocdata->sample_size;
   while(!endofvoc && !al_feof(vocdata->file)) {
      uint32_t blocktype = 0;
      uint32_t x = 0, len = 0;
      read = al_fread(vocdata->file, buffer, bytestoread);
      pos += read;
      READNBYTES(vocdata->file, blocktype, 1, NULL);   // read next block type
      if (al_feof(vocdata->file)) break;
      switch (blocktype) {
         case 0:{  /* we found a terminator block */
            endofvoc = true;
            break;
            }
         case 2:{  /*we found a continuation block: unlikely but handled */
            x = 0;
            bytestoread = 0;
            READNBYTES(vocdata->file, bytestoread, 2, NULL);
            READNBYTES(vocdata->file, x, 1, NULL);
            bytestoread += x<<16;
            /* increase subsequently storage */
            buffer = al_realloc(buffer, sizeof(buffer) + bytestoread);
            break;
            }
         case 1:   // we found a NEW data block starter, I assume this is wrong
         case 8:   // and let the so far read sample data correctly in the
         case 9:{   // already allocated buffer.
            endofvoc = true;
            break;
            }
         case 3:     /* we found a pause block */
         case 4:     /* we found a marker block */
         case 5:     /* we found an ASCII c-string block */
         case 6:     /* we found a repeat block */
         case 7:{    /* we found an end repeat block */
                     /* all these blocks will be skipped */
            unsigned int ii;
            len = 0;
            x = 0;
            READNBYTES(vocdata->file, len, 2, NULL);
            READNBYTES(vocdata->file, x, 1, NULL);
            len += x<<16;  // this is the length what's left to skip */
            for (ii = 0; ii < len ; ++ii) {
               al_fgetc(vocdata->file);
            }
            bytestoread = 0;  //should let safely check for the next block */
            break;
            }
         default:
            break;
      }
   }

   sample = al_create_sample(buffer, pos, vocdata->samplerate,
                             _al_word_size_to_depth_conf(vocdata->sample_size),
                             _al_count_to_channel_conf(vocdata->channels),
                             true);
   if (!sample)
      al_free(buffer);

   voc_close(vocdata);

   return sample;
}