[gegl/video-rejuvenation: 19/30] ui: use SDL for hacky audio playback
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/video-rejuvenation: 19/30] ui: use SDL for hacky audio playback
- Date: Tue, 27 Oct 2015 13:48:07 +0000 (UTC)
commit 340459738cb2e9fff0e895db51257e42a79c8835
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Oct 14 13:00:44 2015 +0200
ui: use SDL for hacky audio playback
bin/Makefile.am | 2 +
bin/mrg-ui.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 136 insertions(+), 10 deletions(-)
---
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 91fc956..2413926 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -44,6 +44,8 @@ gegl_tester_SOURCES = \
if HAVE_MRG
gegl_SOURCES += mrg-ui.c
+AM_CFLAGS += $(SDL_CFLAGS)
+AM_LDFLAGS += $(SDL_LIBS)
endif
if HAVE_SPIRO
diff --git a/bin/mrg-ui.c b/bin/mrg-ui.c
index 5cdb0e3..f6b2e45 100644
--- a/bin/mrg-ui.c
+++ b/bin/mrg-ui.c
@@ -39,6 +39,8 @@
#include <gegl.h>
#include <gexiv2/gexiv2.h>
#include <gegl-paramspecs.h>
+#include <SDL.h>
+#include <gegl-audio.h>
/* comment this out, and things render more correctly but much slower
* for images larger than your screen/window resolution
@@ -49,6 +51,49 @@
*/
#define DEBUG_OP_LIST 0
+
+static int audio_len = 0;
+static int audio_pos = 0;
+static int audio_post = 0;
+static int audio_start = 0; /* which sample no is at the start of our circular buffer */
+
+#define AUDIO_BUF_LEN 819200000
+
+int16_t audio_data[AUDIO_BUF_LEN];
+
+static void sdl_audio_cb(void *udata, Uint8 *stream, int len)
+{
+ int audio_remaining = audio_len - audio_pos;
+ if (audio_remaining < 0)
+ return;
+
+ if (audio_remaining < len) len = audio_remaining;
+
+ //SDL_MixAudio(stream, (uint8_t*)&audio_data[audio_pos/2], len, SDL_MIX_MAXVOLUME);
+ memcpy (stream, (uint8_t*)&audio_data[audio_pos/2], len);
+ audio_pos += len;
+ audio_post += len;
+ if (audio_pos >= AUDIO_BUF_LEN)
+ {
+ audio_pos = 0;
+ }
+}
+
+static void sdl_add_audio_sample (int sample_pos, float left, float right)
+{
+ audio_data[audio_len/2 + 0] = left * 32767.0;
+ audio_data[audio_len/2 + 1] = right * 32767.0;
+ audio_len += 4;
+
+ if (audio_len >= AUDIO_BUF_LEN)
+ {
+ audio_len = 0;
+ }
+}
+
+static int audio_started = 0;
+
+
/* this structure contains the full application state, and is what
* re-renderings of the UI is directly based on.
*/
@@ -169,6 +214,7 @@ static void drag_preview (MrgEvent *e);
static void load_into_buffer (State *o, const char *path);
static GeglNode *locate_node (State *o, const char *op_name);
static void zoom_to_fit (State *o);
+static void center (State *o);
static void zoom_to_fit_buffer (State *o);
static void go_next_cb (MrgEvent *event, void *data1, void *data2);
@@ -289,10 +335,40 @@ static State *hack_state = NULL; // XXX: this shoudl be factored away
char **ops = NULL;
+
+static void init_audio (void)
+{
+ SDL_AudioSpec AudioSettings = {0};
+
+ SDL_Init(SDL_INIT_AUDIO);
+ AudioSettings.freq = 48000;
+ AudioSettings.format = AUDIO_S16SYS;
+ AudioSettings.channels = 2;
+ AudioSettings.samples = 1024;
+ AudioSettings.callback = sdl_audio_cb;
+ SDL_OpenAudio(&AudioSettings, 0);
+
+ if (AudioSettings.format != AUDIO_S16SYS)
+ {
+ fprintf (stderr, "not getting format we wanted\n");
+ }
+ if (AudioSettings.freq != 48000)
+ {
+ fprintf (stderr, "not getting rate we wanted\n");
+ }
+}
+
+static void end_audio (void)
+{
+
+}
+
int mrg_ui_main (int argc, char **argv, char **ops)
{
Mrg *mrg = mrg_new (1024, 768, NULL);
State o = {NULL,};
+
+ init_audio ();
#ifdef USE_MIPMAPS
/* to use this UI comfortably, mipmap rendering needs to be enabled, there are
* still a few glitches, but for basic full frame un-panned, un-cropped use it
@@ -350,6 +426,8 @@ int mrg_ui_main (int argc, char **argv, char **ops)
o.buffer = NULL;
}
gegl_exit ();
+
+ end_audio ();
return 0;
}
@@ -926,6 +1004,7 @@ static void gegl_ui (Mrg *mrg, void *data)
{
o->frame_no++;
gegl_node_set (o->load, "frame", o->frame_no, NULL);
+ mrg_queue_draw (o->mrg, NULL);
}
mrg_gegl_blit (mrg,
@@ -935,6 +1014,32 @@ static void gegl_ui (Mrg *mrg, void *data)
o->u, o->v,
o->scale,
o->render_quality);
+
+ {
+ GeglAudio *audio = NULL;
+ gdouble fps;
+ gegl_node_get (o->load, "audio", &audio, "frame-rate", &fps, NULL);
+ if (audio->samples > 0)
+ {
+ int i;
+ if (!audio_started)
+ {
+ SDL_PauseAudio(0);
+ audio_started = 1;
+ }
+ for (i = 0; i < audio->samples; i++)
+ {
+ sdl_add_audio_sample (0, audio->left[i], audio->right[i]);
+ }
+ }
+
+ while ( (audio_post / 4.0) / audio->samplerate < (o->frame_no / fps) - 0.05 )
+ {
+ g_usleep (500); /* sync audio */
+ }
+
+ g_object_unref (audio);
+ }
if (o->show_controls)
{
@@ -1246,7 +1351,12 @@ static void load_path (State *o)
struct stat stat_buf;
lstat (o->path, &stat_buf);
if (S_ISREG (stat_buf.st_mode))
- zoom_to_fit (o);
+ {
+ if (o->is_video)
+ center (o);
+ else
+ zoom_to_fit (o);
+ }
}
if (o->ops)
@@ -1483,11 +1593,23 @@ static void zoom_to_fit (State *o)
o->scale = scale;
- o->u = -(mrg_width (mrg) - rect.width * scale) / 2;
- o->v = -(mrg_height (mrg) - rect.height * scale) / 2;
-
- o->u += rect.x * scale;
- o->v += rect.y * scale;
+ o->u = -(mrg_width (mrg) - rect.width * o->scale) / 2;
+ o->v = -(mrg_height (mrg) - rect.height * o->scale) / 2;
+ o->u += rect.x * o->scale;
+ o->v += rect.y * o->scale;
+
+ mrg_queue_draw (mrg, NULL);
+}
+static void center (State *o)
+{
+ Mrg *mrg = o->mrg;
+ GeglRectangle rect = gegl_node_get_bounding_box (o->sink);
+ o->scale = 1.0;
+
+ o->u = -(mrg_width (mrg) - rect.width * o->scale) / 2;
+ o->v = -(mrg_height (mrg) - rect.height * o->scale) / 2;
+ o->u += rect.x * o->scale;
+ o->v += rect.y * o->scale;
mrg_queue_draw (mrg, NULL);
}
@@ -1504,10 +1626,12 @@ static void zoom_to_fit_buffer (State *o)
if (scale2 < scale) scale = scale2;
o->scale = scale;
- o->u = -(mrg_width (mrg) - rect.width * scale) / 2;
- o->v = -(mrg_height (mrg) - rect.height * scale) / 2;
- o->u += rect.x * scale;
- o->v += rect.y * scale;
+ o->u = -(mrg_width (mrg) - rect.width * o->scale) / 2;
+ o->v = -(mrg_height (mrg) - rect.height * o->scale) / 2;
+ o->u += rect.x * o->scale;
+ o->v += rect.y * o->scale;
+
+
mrg_queue_draw (mrg, NULL);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]