Vaclav Slavik - Sun Sep 8 18:57:38 PDT 2002
authorSam Lantinga <slouken@libsdl.org>
Mon, 09 Sep 2002 01:59:14 +0000
changeset 1906c92264b847d
parent 189 983b27be0ec8
child 191 67a813176727
Vaclav Slavik - Sun Sep 8 18:57:38 PDT 2002
* Added support for loading Ogg Vorbis samples as an audio chunk
CHANGES
Makefile.am
load_ogg.c
load_ogg.h
mixer.c
     1.1 --- a/CHANGES	Sun Aug 25 05:12:43 2002 +0000
     1.2 +++ b/CHANGES	Mon Sep 09 01:59:14 2002 +0000
     1.3 @@ -1,5 +1,7 @@
     1.4  
     1.5  1.2.5:
     1.6 +Vaclav Slavik - Sun Sep  8 18:57:38 PDT 2002
     1.7 + * Added support for loading Ogg Vorbis samples as an audio chunk
     1.8  Martin Storsjö - Tue Jul 16 10:38:12 PDT 2002
     1.9   * Fixed to start playing another sample immediately when one finishes
    1.10  Martin Storsjö - Tue May 28 13:08:29 PDT 2002
     2.1 --- a/Makefile.am	Sun Aug 25 05:12:43 2002 +0000
     2.2 +++ b/Makefile.am	Mon Sep 09 01:59:14 2002 +0000
     2.3 @@ -14,6 +14,8 @@
     2.4  	load_aiff.h		\
     2.5  	load_voc.c		\
     2.6  	load_voc.h		\
     2.7 +	load_ogg.c		\
     2.8 +	load_ogg.h		\
     2.9  	mixer.c			\
    2.10  	music.c			\
    2.11  	music_cmd.c		\
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/load_ogg.c	Mon Sep 09 01:59:14 2002 +0000
     3.3 @@ -0,0 +1,152 @@
     3.4 +/*
     3.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     3.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     3.7 +
     3.8 +    This library is free software; you can redistribute it and/or
     3.9 +    modify it under the terms of the GNU Library General Public
    3.10 +    License as published by the Free Software Foundation; either
    3.11 +    version 2 of the License, or (at your option) any later version.
    3.12 +
    3.13 +    This library is distributed in the hope that it will be useful,
    3.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.16 +    Library General Public License for more details.
    3.17 +
    3.18 +    You should have received a copy of the GNU Library General Public
    3.19 +    License along with this library; if not, write to the Free
    3.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.21 +
    3.22 +    This is the source needed to decode an Ogg Vorbis into a waveform.
    3.23 +    This file by Vaclav Slavik (vaclav.slavik@matfyz.cz).
    3.24 +*/
    3.25 +
    3.26 +/* $Id$ */
    3.27 +
    3.28 +#ifdef OGG_MUSIC
    3.29 +
    3.30 +#include <stdio.h>
    3.31 +#include <stdlib.h>
    3.32 +#include <string.h>
    3.33 +#include <vorbis/vorbisfile.h>
    3.34 +
    3.35 +#include "SDL_mutex.h"
    3.36 +#include "SDL_endian.h"
    3.37 +#include "SDL_timer.h"
    3.38 +
    3.39 +#include "SDL_mixer.h"
    3.40 +#include "load_ogg.h"
    3.41 +
    3.42 +static size_t sdl_read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
    3.43 +{
    3.44 +    return SDL_RWread((SDL_RWops*)datasource, ptr, size, nmemb);
    3.45 +}
    3.46 +
    3.47 +static int sdl_seek_func(void *datasource, ogg_int64_t offset, int whence)
    3.48 +{
    3.49 +    return SDL_RWseek((SDL_RWops*)datasource, offset, whence);
    3.50 +}
    3.51 +
    3.52 +static int sdl_close_func_freesrc(void *datasource)
    3.53 +{
    3.54 +    return SDL_RWclose((SDL_RWops*)datasource);
    3.55 +}
    3.56 +
    3.57 +static int sdl_close_func_nofreesrc(void *datasource)
    3.58 +{
    3.59 +    return SDL_RWseek((SDL_RWops*)datasource, 0, SEEK_SET);
    3.60 +}
    3.61 +
    3.62 +static long sdl_tell_func(void *datasource)
    3.63 +{
    3.64 +    return SDL_RWtell((SDL_RWops*)datasource);
    3.65 +}
    3.66 +
    3.67 +
    3.68 +/* don't call this directly; use Mix_LoadWAV_RW() for now. */
    3.69 +SDL_AudioSpec *Mix_LoadOGG_RW (SDL_RWops *src, int freesrc,
    3.70 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
    3.71 +{
    3.72 +    OggVorbis_File vf;
    3.73 +    ov_callbacks callbacks;
    3.74 +    vorbis_info *info;
    3.75 +    Uint8 *buf;
    3.76 +    int bitstream = -1;
    3.77 +    long samplesize;
    3.78 +    long samples;
    3.79 +    int read, to_read;
    3.80 +    int must_close = 1;
    3.81 +    int was_error = 1;
    3.82 +    
    3.83 +    if ( (!src) || (!audio_buf) || (!audio_len) )   /* sanity checks. */
    3.84 +        goto done;
    3.85 +
    3.86 +    callbacks.read_func = sdl_read_func;
    3.87 +    callbacks.seek_func = sdl_seek_func;
    3.88 +    callbacks.tell_func = sdl_tell_func;
    3.89 +    callbacks.close_func = freesrc ? 
    3.90 +                           sdl_close_func_freesrc : sdl_close_func_nofreesrc;
    3.91 +
    3.92 +    if (ov_open_callbacks(src, &vf, NULL, 0, callbacks) != 0)
    3.93 +    {
    3.94 +        SDL_SetError("OGG bitstream is not valid Vorbis stream!");
    3.95 +        goto done;
    3.96 +    }
    3.97 +
    3.98 +    must_close = 0;
    3.99 +    
   3.100 +    info = ov_info(&vf, -1);
   3.101 +    
   3.102 +    *audio_buf = NULL;
   3.103 +    *audio_len = 0;
   3.104 +    memset(spec, '\0', sizeof (SDL_AudioSpec));
   3.105 +
   3.106 +    spec->format = AUDIO_S16;
   3.107 +    spec->channels = info->channels;
   3.108 +    spec->freq = info->rate;
   3.109 +    spec->samples = 4096; /* buffer size */
   3.110 +    
   3.111 +    samples = ov_pcm_total(&vf, -1);
   3.112 +
   3.113 +    *audio_len = spec->size = samples * spec->channels * 2;
   3.114 +    *audio_buf = malloc(*audio_len);
   3.115 +    if (*audio_buf == NULL)
   3.116 +        goto done;
   3.117 +
   3.118 +    buf = *audio_buf;
   3.119 +    to_read = *audio_len;
   3.120 +    for (read = ov_read(&vf, buf, to_read, 0/*LE*/, 2/*16bit*/, 1/*signed*/, &bitstream);
   3.121 +         read > 0;
   3.122 +         read = ov_read(&vf, buf, to_read, 0, 2, 1, &bitstream))
   3.123 +    {
   3.124 +        if (read == OV_HOLE || read == OV_EBADLINK)
   3.125 +            break; /* error */
   3.126 +        
   3.127 +        to_read -= read;
   3.128 +        buf += read;
   3.129 +    }
   3.130 +
   3.131 +    ov_clear(&vf);
   3.132 +    was_error = 0;
   3.133 +
   3.134 +    /* Don't return a buffer that isn't a multiple of samplesize */
   3.135 +    samplesize = ((spec->format & 0xFF)/8)*spec->channels;
   3.136 +    *audio_len &= ~(samplesize-1);
   3.137 +
   3.138 +done:
   3.139 +    if (src && must_close)
   3.140 +    {
   3.141 +        if (freesrc)
   3.142 +            SDL_RWclose(src);
   3.143 +        else
   3.144 +            SDL_RWseek(src, 0, SEEK_SET);
   3.145 +    }
   3.146 +
   3.147 +    if ( was_error )
   3.148 +        spec = NULL;
   3.149 +
   3.150 +    return(spec);
   3.151 +} /* Mix_LoadOGG_RW */
   3.152 +
   3.153 +/* end of load_ogg.c ... */
   3.154 +
   3.155 +#endif
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/load_ogg.h	Mon Sep 09 01:59:14 2002 +0000
     4.3 @@ -0,0 +1,29 @@
     4.4 +/*
     4.5 +    SDL_mixer:  An audio mixer library based on the SDL library
     4.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Library General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Library General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Library General Public
    4.19 +    License along with this library; if not, write to the Free
    4.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 +
    4.22 +    This is the source needed to decode an Ogg Vorbis into a waveform.
    4.23 +    This file by Vaclav Slavik (vaclav.slavik@matfyz.cz).
    4.24 +*/
    4.25 +
    4.26 +/* $Id$ */
    4.27 +
    4.28 +#ifdef OGG_MUSIC
    4.29 +/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
    4.30 +SDL_AudioSpec *Mix_LoadOGG_RW (SDL_RWops *src, int freesrc,
    4.31 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
    4.32 +#endif
     5.1 --- a/mixer.c	Sun Aug 25 05:12:43 2002 +0000
     5.2 +++ b/mixer.c	Mon Sep 09 01:59:14 2002 +0000
     5.3 @@ -33,11 +33,13 @@
     5.4  #include "SDL_mixer.h"
     5.5  #include "load_aiff.h"
     5.6  #include "load_voc.h"
     5.7 +#include "load_ogg.h"
     5.8  
     5.9  /* Magic numbers for various audio file formats */
    5.10  #define RIFF		0x46464952		/* "RIFF" */
    5.11  #define WAVE		0x45564157		/* "WAVE" */
    5.12  #define FORM		0x4d524f46		/* "FORM" */
    5.13 +#define OGGS		0x5367674f		/* "OggS" */
    5.14  
    5.15  static int audio_opened = 0;
    5.16  static SDL_AudioSpec mixer;
    5.17 @@ -429,6 +431,12 @@
    5.18  			loaded = Mix_LoadAIFF_RW(src, freesrc, &wavespec,
    5.19  					(Uint8 **)&chunk->abuf, &chunk->alen);
    5.20  			break;
    5.21 +#ifdef OGG_MUSIC
    5.22 +		case OGGS:
    5.23 +			loaded = Mix_LoadOGG_RW(src, freesrc, &wavespec,
    5.24 +					(Uint8 **)&chunk->abuf, &chunk->alen);
    5.25 +			break;
    5.26 +#endif
    5.27  		default:
    5.28  			loaded = Mix_LoadVOC_RW(src, freesrc, &wavespec,
    5.29  					(Uint8 **)&chunk->abuf, &chunk->alen);