Back to index

libsfml  1.6+dfsg2
Classes | Typedefs | Enumerations | Functions
stb_vorbis.h File Reference
#include <stdio.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  stb_vorbis_alloc
struct  stb_vorbis_info

Typedefs

typedef struct stb_vorbis

Enumerations

enum  STBVorbisError {
  VORBIS__no_error, VORBIS_need_more_data = 1, VORBIS_invalid_api_mixing, VORBIS_outofmem,
  VORBIS_feature_not_supported, VORBIS_too_many_channels, VORBIS_file_open_failure, VORBIS_seek_without_length,
  VORBIS_unexpected_eof = 10, VORBIS_seek_invalid, VORBIS_invalid_setup = 20, VORBIS_invalid_stream,
  VORBIS_missing_capture_pattern = 30, VORBIS_invalid_stream_structure_version, VORBIS_continued_packet_flag_invalid, VORBIS_incorrect_stream_serial_number,
  VORBIS_invalid_first_page, VORBIS_bad_packet_type, VORBIS_cant_find_last_page, VORBIS_seek_failed
}

Functions

stb_vorbis_info stb_vorbis_get_info (stb_vorbis *f)
int stb_vorbis_get_error (stb_vorbis *f)
void stb_vorbis_close (stb_vorbis *f)
int stb_vorbis_get_sample_offset (stb_vorbis *f)
unsigned int stb_vorbis_get_file_offset (stb_vorbis *f)
stb_vorbisstb_vorbis_open_pushdata (unsigned char *datablock, int datablock_length_in_bytes, int *datablock_memory_consumed_in_bytes, int *error, stb_vorbis_alloc *alloc_buffer)
int stb_vorbis_decode_frame_pushdata (stb_vorbis *f, unsigned char *datablock, int datablock_length_in_bytes, int *channels, float ***output, int *samples)
void stb_vorbis_flush_pushdata (stb_vorbis *f)
int stb_vorbis_decode_filename (char *filename, int *channels, short **output)
int stb_vorbis_decode_memory (unsigned char *mem, int len, int *channels, short **output)
stb_vorbisstb_vorbis_open_memory (unsigned char *data, int len, int *error, stb_vorbis_alloc *alloc_buffer)
stb_vorbisstb_vorbis_open_filename (char *filename, int *error, stb_vorbis_alloc *alloc_buffer)
stb_vorbisstb_vorbis_open_file (FILE *f, int close_handle_on_close, int *error, stb_vorbis_alloc *alloc_buffer)
stb_vorbisstb_vorbis_open_file_section (FILE *f, int close_handle_on_close, int *error, stb_vorbis_alloc *alloc_buffer, unsigned int len)
int stb_vorbis_seek_frame (stb_vorbis *f, unsigned int sample_number)
int stb_vorbis_seek (stb_vorbis *f, unsigned int sample_number)
void stb_vorbis_seek_start (stb_vorbis *f)
unsigned int stb_vorbis_stream_length_in_samples (stb_vorbis *f)
float stb_vorbis_stream_length_in_seconds (stb_vorbis *f)
int stb_vorbis_get_frame_float (stb_vorbis *f, int *channels, float ***output)
int stb_vorbis_get_frame_short_interleaved (stb_vorbis *f, int num_c, short *buffer, int num_shorts)
int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples)
int stb_vorbis_get_samples_float_interleaved (stb_vorbis *f, int channels, float *buffer, int num_floats)
int stb_vorbis_get_samples_float (stb_vorbis *f, int channels, float **buffer, int num_samples)
int stb_vorbis_get_samples_short_interleaved (stb_vorbis *f, int channels, short *buffer, int num_shorts)
int stb_vorbis_get_samples_short (stb_vorbis *f, int channels, short **buffer, int num_samples)

Class Documentation

struct stb_vorbis_alloc

Definition at line 79 of file stb_vorbis.h.

Class Members
char * alloc_buffer
int alloc_buffer_length_in_bytes
struct stb_vorbis_info

Definition at line 90 of file stb_vorbis.h.

Class Members
int channels
int max_frame_size
unsigned int sample_rate
unsigned int setup_memory_required
unsigned int setup_temp_memory_required
unsigned int temp_memory_required

Typedef Documentation

typedef struct stb_vorbis

Definition at line 88 of file stb_vorbis.h.


Enumeration Type Documentation

Enumerator:
VORBIS__no_error 
VORBIS_need_more_data 
VORBIS_invalid_api_mixing 
VORBIS_outofmem 
VORBIS_feature_not_supported 
VORBIS_too_many_channels 
VORBIS_file_open_failure 
VORBIS_seek_without_length 
VORBIS_unexpected_eof 
VORBIS_seek_invalid 
VORBIS_invalid_setup 
VORBIS_invalid_stream 
VORBIS_missing_capture_pattern 
VORBIS_invalid_stream_structure_version 
VORBIS_continued_packet_flag_invalid 
VORBIS_incorrect_stream_serial_number 
VORBIS_invalid_first_page 
VORBIS_bad_packet_type 
VORBIS_cant_find_last_page 
VORBIS_seek_failed 

Definition at line 314 of file stb_vorbis.h.

{
   VORBIS__no_error,

   VORBIS_need_more_data=1,             // not a real error

   VORBIS_invalid_api_mixing,           // can't mix API modes
   VORBIS_outofmem,                     // not enough memory
   VORBIS_feature_not_supported,        // uses floor 0
   VORBIS_too_many_channels,            // STB_VORBIS_MAX_CHANNELS is too small
   VORBIS_file_open_failure,            // fopen() failed
   VORBIS_seek_without_length,          // can't seek in unknown-length file

   VORBIS_unexpected_eof=10,            // file is truncated?
   VORBIS_seek_invalid,                 // seek past EOF

   // decoding errors (corrupt/invalid stream) -- you probably
   // don't care about the exact details of these

   // vorbis errors:
   VORBIS_invalid_setup=20,
   VORBIS_invalid_stream,

   // ogg errors:
   VORBIS_missing_capture_pattern=30,
   VORBIS_invalid_stream_structure_version,
   VORBIS_continued_packet_flag_invalid,
   VORBIS_incorrect_stream_serial_number,
   VORBIS_invalid_first_page,
   VORBIS_bad_packet_type,
   VORBIS_cant_find_last_page,
   VORBIS_seek_failed
};

Function Documentation

Definition at line 3821 of file stb_vorbis.c.

{
   if (p == NULL) return;
   vorbis_deinit(p);
   setup_free(p,p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int stb_vorbis_decode_filename ( char *  filename,
int *  channels,
short **  output 
)

Definition at line 4915 of file stb_vorbis.c.

{
   int data_len, offset, total, limit, error;
   short *data;
   stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL);
   if (v == NULL) return -1;
   limit = v->channels * 4096;
   *channels = v->channels;
   offset = data_len = 0;
   total = limit;
   data = (short *) malloc(total * sizeof(*data));
   if (data == NULL) {
      stb_vorbis_close(v);
      return -2;
   }
   for (;;) {
      int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset);
      if (n == 0) break;
      data_len += n;
      offset += n * v->channels;
      if (offset + limit > total) {
         short *data2;
         total *= 2;
         data2 = (short *) realloc(data, total * sizeof(*data));
         if (data2 == NULL) {
            free(data);
            stb_vorbis_close(v);
            return -2;
         }
         data = data2;
      }
   }
   *output = data;
   return data_len;
}

Here is the call graph for this function:

int stb_vorbis_decode_frame_pushdata ( stb_vorbis f,
unsigned char *  datablock,
int  datablock_length_in_bytes,
int *  channels,
float ***  output,
int *  samples 
)

Definition at line 3985 of file stb_vorbis.c.

{
   int i;
   int len,right,left;

   if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);

   if (f->page_crc_tests >= 0) {
      *samples = 0;
      return vorbis_search_for_page_pushdata(f, data, data_len);
   }

   f->stream     = data;
   f->stream_end = data + data_len;
   f->error      = VORBIS__no_error;

   // check that we have the entire packet in memory
   if (!is_whole_packet_present(f, FALSE)) {
      *samples = 0;
      return 0;
   }

   if (!vorbis_decode_packet(f, &len, &left, &right)) {
      // save the actual error we encountered
      enum STBVorbisError error = f->error;
      if (error == VORBIS_bad_packet_type) {
         // flush and resynch
         f->error = VORBIS__no_error;
         while (get8_packet(f) != EOP)
            if (f->eof) break;
         *samples = 0;
         return f->stream - data;
      }
      if (error == VORBIS_continued_packet_flag_invalid) {
         if (f->previous_length == 0) {
            // we may be resynching, in which case it's ok to hit one
            // of these; just discard the packet
            f->error = VORBIS__no_error;
            while (get8_packet(f) != EOP)
               if (f->eof) break;
            *samples = 0;
            return f->stream - data;
         }
      }
      // if we get an error while parsing, what to do?
      // well, it DEFINITELY won't work to continue from where we are!
      stb_vorbis_flush_pushdata(f);
      // restore the error that actually made us bail
      f->error = error;
      *samples = 0;
      return 1;
   }

   // success!
   len = vorbis_finish_frame(f, len, left, right);
   for (i=0; i < f->channels; ++i)
      f->outputs[i] = f->channel_buffers[i] + left;

   if (channels) *channels = f->channels;
   *samples = len;
   *output = f->outputs;
   return f->stream - data;
}

Here is the call graph for this function:

int stb_vorbis_decode_memory ( unsigned char *  mem,
int  len,
int *  channels,
short **  output 
)

Definition at line 4952 of file stb_vorbis.c.

{
   int data_len, offset, total, limit, error;
   short *data;
   stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL);
   if (v == NULL) return -1;
   limit = v->channels * 4096;
   *channels = v->channels;
   offset = data_len = 0;
   total = limit;
   data = (short *) malloc(total * sizeof(*data));
   if (data == NULL) {
      stb_vorbis_close(v);
      return -2;
   }
   for (;;) {
      int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset);
      if (n == 0) break;
      data_len += n;
      offset += n * v->channels;
      if (offset + limit > total) {
         short *data2;
         total *= 2;
         data2 = (short *) realloc(data, total * sizeof(*data));
         if (data2 == NULL) {
            free(data);
            stb_vorbis_close(v);
            return -2;
         }
         data = data2;
      }
   }
   *output = data;
   return data_len;
}

Here is the call graph for this function:

Definition at line 3882 of file stb_vorbis.c.

{
   f->previous_length = 0;
   f->page_crc_tests  = 0;
   f->discard_samples_deferred = 0;
   f->current_loc_valid = FALSE;
   f->first_decode = FALSE;
   f->samples_output = 0;
   f->channel_buffer_start = 0;
   f->channel_buffer_end = 0;
}

Here is the caller graph for this function:

Definition at line 3867 of file stb_vorbis.c.

{
   int e = f->error;
   f->error = VORBIS__no_error;
   return e;
}
unsigned int stb_vorbis_get_file_offset ( stb_vorbis f)

Definition at line 4085 of file stb_vorbis.c.

{
   #ifndef STB_VORBIS_NO_PUSHDATA_API
   if (f->push_mode) return 0;
   #endif
   if (USE_MEMORY(f)) return f->stream - f->stream_start;
   #ifndef STB_VORBIS_NO_STDIO
   return ftell(f->f) - f->f_start;
   #endif
}

Here is the caller graph for this function:

int stb_vorbis_get_frame_float ( stb_vorbis f,
int *  channels,
float ***  output 
)

Definition at line 4609 of file stb_vorbis.c.

{
   int len, right,left,i;
   if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);

   if (!vorbis_decode_packet(f, &len, &left, &right)) {
      f->channel_buffer_start = f->channel_buffer_end = 0;
      return 0;
   }

   len = vorbis_finish_frame(f, len, left, right);
   for (i=0; i < f->channels; ++i)
      f->outputs[i] = f->channel_buffers[i] + left;

   f->channel_buffer_start = left;
   f->channel_buffer_end   = left+len;

   if (channels) *channels = f->channels;
   if (output)   *output = f->outputs;
   return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int stb_vorbis_get_frame_short ( stb_vorbis f,
int  num_c,
short **  buffer,
int  num_samples 
)

Definition at line 4826 of file stb_vorbis.c.

{
   float **output;
   int len = stb_vorbis_get_frame_float(f, NULL, &output);
   if (len > num_samples) len = num_samples;
   if (len)
      convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len);
   return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int stb_vorbis_get_frame_short_interleaved ( stb_vorbis f,
int  num_c,
short *  buffer,
int  num_shorts 
)

Definition at line 4861 of file stb_vorbis.c.

{
   float **output;
   int len;
   if (num_c == 1) return stb_vorbis_get_frame_short(f,num_c,&buffer, num_shorts);
   len = stb_vorbis_get_frame_float(f, NULL, &output);
   if (len) {
      if (len*num_c > num_shorts) len = num_shorts / num_c;
      convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len);
   }
   return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3855 of file stb_vorbis.c.

Here is the caller graph for this function:

Definition at line 3847 of file stb_vorbis.c.

{
   if (f->current_loc_valid)
      return f->current_loc;
   else
      return -1;
}
int stb_vorbis_get_samples_float ( stb_vorbis f,
int  channels,
float **  buffer,
int  num_samples 
)

Definition at line 5014 of file stb_vorbis.c.

{
   float **outputs;
   int n=0;
   int z = f->channels;
   if (z > channels) z = channels;
   while (n < num_samples) {
      int i;
      int k = f->channel_buffer_end - f->channel_buffer_start;
      if (n+k >= num_samples) k = num_samples - n;
      if (k) {
         for (i=0; i < z; ++i)
            memcpy(buffer[i]+n, f->channel_buffers+f->channel_buffer_start, sizeof(float)*k);
         for (   ; i < channels; ++i)
            memset(buffer[i]+n, 0, sizeof(float) * k);
      }
      n += k;
      f->channel_buffer_start += k;
      if (n == num_samples) break;
      if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
   }
   return n;
}

Here is the call graph for this function:

int stb_vorbis_get_samples_float_interleaved ( stb_vorbis f,
int  channels,
float *  buffer,
int  num_floats 
)

Definition at line 4989 of file stb_vorbis.c.

{
   float **outputs;
   int len = num_floats / channels;
   int n=0;
   int z = f->channels;
   if (z > channels) z = channels;
   while (n < len) {
      int i,j;
      int k = f->channel_buffer_end - f->channel_buffer_start;
      if (n+k >= len) k = len - n;
      for (j=0; j < k; ++j) {
         for (i=0; i < z; ++i)
            *buffer++ = f->channel_buffers[i][f->channel_buffer_start+j];
         for (   ; i < channels; ++i)
            *buffer++ = 0;
      }
      n += k;
      f->channel_buffer_start += k;
      if (n == len) break;
      if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
   }
   return n;
}

Here is the call graph for this function:

int stb_vorbis_get_samples_short ( stb_vorbis f,
int  channels,
short **  buffer,
int  num_samples 
)

Definition at line 4895 of file stb_vorbis.c.

{
   float **outputs;
   int n=0;
   int z = f->channels;
   if (z > channels) z = channels;
   while (n < len) {
      int k = f->channel_buffer_end - f->channel_buffer_start;
      if (n+k >= len) k = len - n;
      if (k)
         convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k);
      n += k;
      f->channel_buffer_start += k;
      if (n == len) break;
      if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
   }
   return n;
}

Here is the call graph for this function:

int stb_vorbis_get_samples_short_interleaved ( stb_vorbis f,
int  channels,
short *  buffer,
int  num_shorts 
)

Definition at line 4874 of file stb_vorbis.c.

{
   float **outputs;
   int len = num_shorts / channels;
   int n=0;
   int z = f->channels;
   if (z > channels) z = channels;
   while (n < len) {
      int k = f->channel_buffer_end - f->channel_buffer_start;
      if (n+k >= len) k = len - n;
      if (k)
         convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k);
      buffer += k*channels;
      n += k;
      f->channel_buffer_start += k;
      if (n == len) break;
      if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break;
   }
   return n;
}

Here is the call graph for this function:

Here is the caller graph for this function:

stb_vorbis* stb_vorbis_open_file ( FILE *  f,
int  close_handle_on_close,
int *  error,
stb_vorbis_alloc alloc_buffer 
)

Definition at line 4654 of file stb_vorbis.c.

{
   unsigned int len, start;
   start = ftell(file);
   fseek(file, 0, SEEK_END);
   len = ftell(file) - start;
   fseek(file, start, SEEK_SET);
   return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

stb_vorbis* stb_vorbis_open_file_section ( FILE *  f,
int  close_handle_on_close,
int *  error,
stb_vorbis_alloc alloc_buffer,
unsigned int  len 
)

Definition at line 4633 of file stb_vorbis.c.

{
   stb_vorbis *f, p;
   vorbis_init(&p, alloc);
   p.f = file;
   p.f_start = ftell(file);
   p.stream_len   = length;
   p.close_on_free = close_on_free;
   if (start_decoder(&p)) {
      f = vorbis_alloc(&p);
      if (f) {
         *f = p;
         vorbis_pump_first_frame(f);
         return f;
      }
   }
   if (error) *error = p.error;
   vorbis_deinit(&p);
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

stb_vorbis* stb_vorbis_open_filename ( char *  filename,
int *  error,
stb_vorbis_alloc alloc_buffer 
)

Definition at line 4664 of file stb_vorbis.c.

{
   FILE *f = fopen(filename, "rb");
   if (f) 
      return stb_vorbis_open_file(f, TRUE, error, alloc);
   if (error) *error = VORBIS_file_open_failure;
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

stb_vorbis* stb_vorbis_open_memory ( unsigned char *  data,
int  len,
int *  error,
stb_vorbis_alloc alloc_buffer 
)

Definition at line 4674 of file stb_vorbis.c.

{
   stb_vorbis *f, p;
   if (data == NULL) return NULL;
   vorbis_init(&p, alloc);
   p.stream = data;
   p.stream_end = data + len;
   p.stream_start = p.stream;
   p.stream_len = len;
   p.push_mode = FALSE;
   if (start_decoder(&p)) {
      f = vorbis_alloc(&p);
      if (f) {
         *f = p;
         vorbis_pump_first_frame(f);
         return f;
      }
   }
   if (error) *error = p.error;
   vorbis_deinit(&p);
   return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

stb_vorbis* stb_vorbis_open_pushdata ( unsigned char *  datablock,
int  datablock_length_in_bytes,
int *  datablock_memory_consumed_in_bytes,
int *  error,
stb_vorbis_alloc alloc_buffer 
)

Definition at line 4055 of file stb_vorbis.c.

{
   stb_vorbis *f, p;
   vorbis_init(&p, alloc);
   p.stream     = data;
   p.stream_end = data + data_len;
   p.push_mode  = TRUE;
   if (!start_decoder(&p)) {
      if (p.eof)
         *error = VORBIS_need_more_data;
      else
         *error = p.error;
      return NULL;
   }
   f = vorbis_alloc(&p);
   if (f) {
      *f = p;
      *data_used = f->stream - data;
      *error = 0;
      return f;
   } else {
      vorbis_deinit(&p);
      return NULL;
   }
}

Here is the call graph for this function:

int stb_vorbis_seek ( stb_vorbis f,
unsigned int  sample_number 
)

Definition at line 4510 of file stb_vorbis.c.

{
   return vorbis_seek_base(f, sample_number, TRUE);
}

Here is the call graph for this function:

int stb_vorbis_seek_frame ( stb_vorbis f,
unsigned int  sample_number 
)

Definition at line 4505 of file stb_vorbis.c.

{
   return vorbis_seek_base(f, sample_number, FALSE);
}

Here is the call graph for this function:

Definition at line 4515 of file stb_vorbis.c.

{
   if (IS_PUSH_MODE(f)) { error(f, VORBIS_invalid_api_mixing); return; }
   set_file_offset(f, f->first_audio_page_offset);
   f->previous_length = 0;
   f->first_decode = TRUE;
   f->next_seg = -1;
   vorbis_pump_first_frame(f);
}

Here is the call graph for this function:

Definition at line 4525 of file stb_vorbis.c.

{
   unsigned int restore_offset, previous_safe;
   unsigned int end, last_page_loc;

   if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing);
   if (!f->total_samples) {
      int last;
      uint32 lo,hi;
      char header[6];

      // first, store the current decode position so we can restore it
      restore_offset = stb_vorbis_get_file_offset(f);

      // now we want to seek back 64K from the end (the last page must
      // be at most a little less than 64K, but let's allow a little slop)
      if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset)
         previous_safe = f->stream_len - 65536;
      else
         previous_safe = f->first_audio_page_offset;

      set_file_offset(f, previous_safe);
      // previous_safe is now our candidate 'earliest known place that seeking
      // to will lead to the final page'

      if (!vorbis_find_page(f, &end, (int unsigned *)&last)) {
         // if we can't find a page, we're hosed!
         f->error = VORBIS_cant_find_last_page;
         f->total_samples = 0xffffffff;
         goto done;
      }

      // check if there are more pages
      last_page_loc = stb_vorbis_get_file_offset(f);

      // stop when the last_page flag is set, not when we reach eof;
      // this allows us to stop short of a 'file_section' end without
      // explicitly checking the length of the section
      while (!last) {
         set_file_offset(f, end);
         if (!vorbis_find_page(f, &end, (int unsigned *)&last)) {
            // the last page we found didn't have the 'last page' flag
            // set. whoops!
            break;
         }
         previous_safe = last_page_loc+1;
         last_page_loc = stb_vorbis_get_file_offset(f);
      }

      set_file_offset(f, last_page_loc);

      // parse the header
      getn(f, (unsigned char *)header, 6);
      // extract the absolute granule position
      lo = get32(f);
      hi = get32(f);
      if (lo == 0xffffffff && hi == 0xffffffff) {
         f->error = VORBIS_cant_find_last_page;
         f->total_samples = SAMPLE_unknown;
         goto done;
      }
      if (hi)
         lo = 0xfffffffe; // saturate
      f->total_samples = lo;

      f->p_last.page_start = last_page_loc;
      f->p_last.page_end   = end;
      f->p_last.last_decoded_sample = lo;
      f->p_last.first_decoded_sample = SAMPLE_unknown;
      f->p_last.after_previous_page_start = previous_safe;

     done:
      set_file_offset(f, restore_offset);
   }
   return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4602 of file stb_vorbis.c.

Here is the call graph for this function: