prosperon/source/engine/datastream.c

114 lines
2.8 KiB
C
Raw Permalink Normal View History

2021-11-30 21:29:18 -06:00
#include "datastream.h"
#include "config.h"
2023-05-12 13:22:05 -05:00
#include "dsp.h"
#include "iir.h"
#include "limits.h"
#include "log.h"
2021-11-30 21:29:18 -06:00
#include "resources.h"
2022-02-06 10:14:57 -06:00
#include "sound.h"
2022-07-02 03:40:50 -05:00
#include "texture.h"
2023-05-12 13:22:05 -05:00
#include <stdbool.h>
2022-07-03 00:43:42 -05:00
#include <stdlib.h>
2023-05-24 20:45:50 -05:00
#include "font.h"
#include "render.h"
2021-11-30 21:29:18 -06:00
2023-08-30 18:22:32 -05:00
#include "cbuf.h"
2023-05-19 09:55:57 -05:00
#include "sokol/sokol_gfx.h"
void datastream_free(datastream *ds)
{
sg_destroy_image(ds->img);
plm_destroy(ds->plm);
free(ds);
}
2023-05-19 09:55:57 -05:00
2023-11-27 14:29:55 -06:00
void soundstream_fillbuf(struct datastream *ds, soundbyte *buf, int frames) {
for (int i = 0; i < frames*CHANNELS; i++)
buf[i] = ringshift(ds->ring);
}
static void render_frame(plm_t *mpeg, plm_frame_t *frame, struct datastream *ds) {
if (ds->dirty) return;
2023-05-19 09:55:57 -05:00
uint8_t rgb[frame->height*frame->width*4];
memset(rgb,255,frame->height*frame->width*4);
2023-05-19 09:55:57 -05:00
plm_frame_to_rgba(frame, rgb, frame->width*4);
sg_image_data imgd = {0};
imgd.subimage[0][0] = SG_RANGE(rgb);
2023-05-19 09:55:57 -05:00
sg_update_image(ds->img, &imgd);
ds->dirty = true;
2021-11-30 21:29:18 -06:00
}
2023-11-27 14:29:55 -06:00
static void render_audio(plm_t *mpeg, plm_samples_t *samples, struct datastream *ds) {
for (int i = 0; i < samples->count * CHANNELS; i++)
ringpush(ds->ring, samples->interleaved[i]);
2021-11-30 21:29:18 -06:00
}
2023-11-27 14:29:55 -06:00
struct datastream *ds_openvideo(const char *path)
{
struct datastream *ds = malloc(sizeof(*ds));
2023-09-27 09:37:20 -05:00
size_t rawlen;
void *raw;
2023-11-27 14:29:55 -06:00
raw = slurp_file(path, &rawlen);
ds->plm = plm_create_with_memory(raw, rawlen, 0);
free(raw);
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
if (!ds->plm) {
2023-11-27 14:29:55 -06:00
YughError("Couldn't open %s", path);
2023-05-12 13:22:05 -05:00
}
2021-11-30 21:29:18 -06:00
2023-11-27 14:29:55 -06:00
YughWarn("Opened %s - framerate: %f, samplerate: %d,audio streams: %d, duration: %g",
path,
2023-08-30 18:22:32 -05:00
plm_get_framerate(ds->plm),
plm_get_samplerate(ds->plm),
plm_get_num_audio_streams(ds->plm),
2023-08-30 18:22:32 -05:00
plm_get_duration(ds->plm));
2023-05-19 09:55:57 -05:00
ds->img = sg_make_image(&(sg_image_desc){
.width = plm_get_width(ds->plm),
.height = plm_get_height(ds->plm),
.usage = SG_USAGE_STREAM,
.type = SG_IMAGETYPE_2D,
.pixel_format = SG_PIXELFORMAT_RGBA8,
2023-05-19 09:55:57 -05:00
});
plm_set_video_decode_callback(ds->plm, render_frame, ds);
return ds;
2023-05-19 09:55:57 -05:00
2023-11-27 14:29:55 -06:00
ds->ring = ringnew(ds->ring, 8192);
2023-11-28 22:48:32 -06:00
plugin_node(make_node(ds, soundstream_fillbuf, NULL), masterbus);
2022-07-06 17:17:06 -05:00
2023-05-12 13:22:05 -05:00
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
plm_set_loop(ds->plm, false);
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
plm_set_audio_enabled(ds->plm, true);
plm_set_audio_stream(ds->plm, 0);
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
// Adjust the audio lead time according to the audio_spec buffer size
plm_set_audio_lead_time(ds->plm, BUF_FRAMES / SAMPLERATE);
2021-11-30 21:29:18 -06:00
2023-11-27 14:29:55 -06:00
return ds;
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_advance(struct datastream *ds, double s) {
ds->dirty = false;
plm_decode(ds->plm, s);
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_seek(struct datastream *ds, double time) {
plm_seek(ds->plm, time, false);
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_advanceframes(struct datastream *ds, int frames) {
for (int i = 0; i < frames; i++) {
plm_frame_t *frame = plm_decode_video(ds->plm);
render_frame(ds->plm, frame, ds);
}
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
double ds_length(struct datastream *ds) {
return plm_get_duration(ds->plm);
2022-02-06 10:14:57 -06:00
}