Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126573
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/ogg/LICENSE.TXT b/util/ogg/LICENSE.TXT
new file mode 100644
index 00000000..410e404b
--- /dev/null
+++ b/util/ogg/LICENSE.TXT
@@ -0,0 +1,22 @@
+Copyright (c) 2007 Trent Gamblin
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/util/ogg/logg.c b/util/ogg/logg.c
new file mode 100644
index 00000000..47b9deee
--- /dev/null
+++ b/util/ogg/logg.c
@@ -0,0 +1,269 @@
+#if defined(HAVE_OGG) && defined(USE_ALLEGRO)
+
+#include <string.h>
+#include <allegro.h>
+#include <allegro/internal/aintern.h>
+
+#include "logg.h"
+
+/* XXX requires testing */
+#ifdef ALLEGRO_BIG_ENDIAN
+ const int ENDIANNESS = 1;
+#endif
+#ifdef ALLEGRO_LITTLE_ENDIAN
+ const int ENDIANNESS = 0;
+#endif
+
+static int logg_bufsize = 1024*64;
+
+SAMPLE* logg_load(const char* filename)
+{
+ OggVorbis_File ovf;
+ FILE* file;
+ vorbis_info* vi;
+ SAMPLE* samp;
+ int numRead;
+ int offset = 0;
+ int bitstream;
+ char *buf = malloc(logg_bufsize);
+
+ file = fopen(filename, "rb");
+ if (!file) {
+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", filename);
+ free(buf);
+ return 0;
+ }
+
+ if (ov_open_callbacks(file, &ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
+ strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
+ fclose(file);
+ free(buf);
+ return 0;
+ }
+
+ vi = ov_info(&ovf, -1);
+
+ samp = (SAMPLE*)_al_malloc(sizeof(SAMPLE));
+ if (!samp) {
+ ov_clear(&ovf);
+ free(buf);
+ return 0;
+ }
+
+ samp->bits = 16;
+ samp->stereo = vi->channels > 1 ? 1 : 0;
+ samp->freq = vi->rate;
+ samp->priority = 128;
+ samp->len = ov_pcm_total(&ovf, -1);
+ samp->loop_start = 0;
+ samp->loop_end = samp->len;
+ samp->data = _al_malloc(sizeof(unsigned short) * samp->len * 2);
+
+ while ((numRead = ov_read(&ovf, buf, logg_bufsize,
+ ENDIANNESS, 2, 0, &bitstream)) != 0) {
+ memcpy((unsigned char*)samp->data+offset, buf, numRead);
+ offset += numRead;
+ }
+
+ ov_clear(&ovf);
+ free(buf);
+
+ return samp;
+}
+
+int logg_get_buffer_size(void)
+{
+ return logg_bufsize;
+}
+
+void logg_set_buffer_size(int size)
+{
+ ASSERT(size > 0);
+ logg_bufsize = size;
+}
+
+static int logg_open_file_for_streaming(struct LOGG_Stream* s)
+{
+ FILE* file;
+ vorbis_info* vi;
+
+ file = fopen(s->filename, "rb");
+ if (!file) {
+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", s->filename);
+ return 1;
+ }
+
+ if (ov_open_callbacks(file, &s->ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
+ strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
+ fclose(file);
+ return 1;
+ }
+
+ vi = ov_info(&s->ovf, -1);
+
+ s->bits = 16;
+ s->stereo = vi->channels > 1 ? 1 : 0;
+ s->freq = vi->rate;
+ s->len = ov_pcm_total(&s->ovf, -1);
+
+ return 0;
+}
+
+static int read_ogg_data(struct LOGG_Stream* s)
+{
+ int read = 0;
+ int bitstream;
+
+ int page = s->current_page;
+ s->current_page++;
+ s->current_page %= OGG_PAGES_TO_BUFFER;
+
+ memset(s->buf[page], 0, logg_bufsize);
+
+ while (read < logg_bufsize) {
+ int thisRead = ov_read(&s->ovf, s->buf[page]+read,
+ logg_bufsize-read,
+ ENDIANNESS, 2, 0, &bitstream);
+ if (thisRead == 0) {
+ if (s->loop) {
+ ov_clear(&s->ovf);
+ if (logg_open_file_for_streaming(s)) {
+ return -1;
+ }
+ }
+ else {
+ return read;
+ }
+ }
+ read += thisRead;
+ }
+
+ return read;
+}
+
+static int logg_play_stream(struct LOGG_Stream* s)
+{
+ int len;
+ int i;
+
+ s->current_page = 0;
+ s->playing_page = -1;
+
+ len = logg_bufsize / (s->stereo ? 2 : 1)
+ / (s->bits / (sizeof(char)*8));
+
+ s->audio_stream = play_audio_stream(len,
+ s->bits, s->stereo,
+ s->freq, s->volume, s->pan);
+
+ if (!s->audio_stream) {
+ return 1;
+ }
+
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ s->buf[i] = malloc(logg_bufsize);
+ if (!s->buf[i]) {
+ logg_destroy_stream(s);
+ return 1;
+ }
+ if (read_ogg_data(s) < 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct LOGG_Stream* logg_get_stream(const char* filename, int volume, int pan, int loop)
+{
+ struct LOGG_Stream* s = calloc(1, sizeof(struct LOGG_Stream));
+ if (!s) {
+ return 0;
+ }
+
+ s->filename = strdup(filename);
+
+ if (!s->filename) {
+ free(s);
+ return 0;
+ }
+
+ if (logg_open_file_for_streaming(s)) {
+ logg_destroy_stream(s);
+ return 0;
+ }
+
+ s->volume = volume;
+ s->pan = pan;
+ s->loop = loop;
+
+ if (logg_play_stream(s)) {
+ logg_destroy_stream(s);
+ return 0;
+ }
+
+ return s;
+}
+
+int logg_update_stream(struct LOGG_Stream* s)
+{
+ unsigned char* data = get_audio_stream_buffer(s->audio_stream);
+
+ if (!data) {
+ if (s->current_page != s->playing_page) {
+ int read = read_ogg_data(s);
+ if (read < logg_bufsize) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+ else {
+ return 1;
+ }
+ }
+
+ s->playing_page++;
+ s->playing_page %= OGG_PAGES_TO_BUFFER;
+ memcpy(data, s->buf[s->playing_page], logg_bufsize);
+
+ free_audio_stream_buffer(s->audio_stream);
+
+ return 1;
+}
+
+void logg_stop_stream(struct LOGG_Stream* s)
+{
+ int i;
+
+ stop_audio_stream(s->audio_stream);
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ free(s->buf[i]);
+ s->buf[i] = 0;
+ }
+}
+
+int logg_restart_stream(struct LOGG_Stream* s)
+{
+ return logg_play_stream(s);
+}
+
+void logg_destroy_stream(struct LOGG_Stream* s)
+{
+ int i;
+
+ if (s->audio_stream) {
+ stop_audio_stream(s->audio_stream);
+ }
+ ov_clear(&s->ovf);
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ if (s->buf[i]) {
+ free(s->buf[i]);
+ }
+ }
+ free(s->filename);
+ free(s);
+}
+
+#endif
diff --git a/util/ogg/logg.h b/util/ogg/logg.h
new file mode 100644
index 00000000..19622722
--- /dev/null
+++ b/util/ogg/logg.h
@@ -0,0 +1,48 @@
+#ifndef LOGG_H
+#define LOGG_H
+
+#if defined(USE_ALLEGRO) && defined(HAVE_OGG)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <allegro.h>
+#include <vorbis/vorbisfile.h>
+
+#define OGG_PAGES_TO_BUFFER 2
+
+struct LOGG_Stream {
+ char *buf[OGG_PAGES_TO_BUFFER];
+ int current_page;
+ int playing_page;
+ AUDIOSTREAM* audio_stream;
+ OggVorbis_File ovf;
+ int bits;
+ int stereo;
+ int freq;
+ int len;
+ char* filename;
+ int loop;
+ int volume;
+ int pan;
+};
+
+extern SAMPLE* logg_load(const char* filename);
+extern int logg_get_buffer_size();
+extern void logg_set_buffer_size(int size);
+extern struct LOGG_Stream* logg_get_stream(const char* filename,
+ int volume, int pan, int loop);
+extern int logg_update_stream(struct LOGG_Stream* s);
+extern void logg_destroy_stream(struct LOGG_Stream* s);
+extern void logg_stop_stream(struct LOGG_Stream* s);
+extern int logg_restart_stream(struct LOGG_Stream* s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // USE_ALLEGRO
+
+#endif
+
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 12:02 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68940
Default Alt Text
(7 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline