prosperon/source/engine/datastream.c

164 lines
4 KiB
C
Raw 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"
#include "mix.h"
#include "render.h"
2021-11-30 21:29:18 -06:00
#include "resources.h"
2023-05-12 13:22:05 -05:00
#include "shader.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 "openglrender.h"
2021-11-30 21:29:18 -06:00
2023-05-19 09:55:57 -05:00
#include "sokol/sokol_gfx.h"
sg_shader vid_shader;
sg_pipeline vid_pipeline;
sg_bindings vid_bind;
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
struct datastream *ds = user;
2023-05-19 09:55:57 -05:00
uint8_t rgb[frame->height*frame->width*4];
plm_frame_to_rgba(frame, rgb, frame->width*4);
sg_image_data imgd;
sg_range ir = {
.ptr = rgb,
.size = frame->height*frame->width*4*sizeof(uint8_t)
};
imgd.subimage[0][0] = ir;
sg_update_image(ds->img, &imgd);
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
struct datastream *ds = user;
short t;
2022-07-06 17:17:06 -05:00
2023-05-12 13:22:05 -05:00
for (int i = 0; i < samples->count * CHANNELS; i++) {
t = (short)(samples->interleaved[i] * SHRT_MAX);
2023-05-30 11:39:22 -05:00
// cbuf_push(ds->astream->buf, t * 5);
2023-05-12 13:22:05 -05:00
}
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
// ds_stop(ds);
char buf[MAXPATH] = {'\0'};
sprintf(buf, "%s%s", "video/", video);
ds->plm = plm_create_with_filename(buf);
2021-11-30 21:29:18 -06:00
2023-05-12 13:22:05 -05:00
if (!ds->plm) {
YughLog(0, 0, "Couldn't open %s", video);
}
2021-11-30 21:29:18 -06:00
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)
});
2023-05-12 13:22:05 -05:00
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
video,
plm_get_framerate(ds->plm),
plm_get_samplerate(ds->plm),
plm_get_num_audio_streams(ds->plm),
plm_get_duration(ds->plm));
2022-07-06 17:17:06 -05:00
2023-05-12 13:22:05 -05:00
ds->astream = soundstream_make();
struct dsp_filter astream_filter;
astream_filter.data = &ds->astream;
astream_filter.filter = soundstream_fillbuf;
2022-07-08 13:54:45 -05:00
2023-05-12 13:22:05 -05:00
// struct dsp_filter lpf = lpf_make(8, 10000);
struct dsp_filter lpf = lpf_make(1, 200);
struct dsp_iir *iir = lpf.data;
iir->in = astream_filter;
2022-07-08 13:54:45 -05:00
2023-05-12 13:22:05 -05:00
struct dsp_filter hpf = hpf_make(1, 2000);
struct dsp_iir *hiir = hpf.data;
hiir->in = astream_filter;
2022-07-08 13:54:45 -05:00
2023-05-12 13:22:05 -05:00
/*
struct dsp_filter llpf = lp_fir_make(20);
struct dsp_fir *fir = llpf.data;
fir->in = astream_filter;
*/
2022-07-08 13:54:45 -05:00
2023-05-12 13:22:05 -05:00
// first_free_bus(astream_filter);
2022-07-06 17:17:06 -05:00
2023-05-12 13:22:05 -05:00
plm_set_video_decode_callback(ds->plm, render_frame, ds);
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-05-12 13:22:05 -05:00
ds->playing = true;
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
struct datastream *MakeDatastream() {
2023-05-24 20:45:50 -05:00
vid_shader = sg_compile_shader("shaders/videovert.glsl", "shaders/videofrag.glsl", &(sg_shader_desc){
2023-05-19 09:55:57 -05:00
.fs.images[0] = {
.name = "video",
.image_type = SG_IMAGETYPE_2D,
.sampler_type = SG_SAMPLERTYPE_FLOAT
}});
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_advance(struct datastream *ds, double s) {
if (ds->playing) {
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) {
// clear_raw(ds->audio_device);
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
void ds_pause(struct datastream *ds) {
ds->playing = false;
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
void ds_stop(struct datastream *ds) {
if (ds->plm != NULL) {
plm_destroy(ds->plm);
ds->plm = NULL;
}
if (ds->audio_device)
close_audio_device(ds->audio_device);
ds->playing = false;
2021-11-30 21:29:18 -06:00
}
// TODO: Must be a better way
2023-05-12 13:22:05 -05:00
int ds_videodone(struct datastream *ds) {
return (ds->plm == NULL) || plm_get_time(ds->plm) >= plm_get_duration(ds->plm);
2021-11-30 21:29:18 -06:00
}
2023-05-12 13:22:05 -05:00
double ds_remainingtime(struct datastream *ds) {
if (ds->plm != NULL)
return plm_get_duration(ds->plm) - plm_get_time(ds->plm);
else
return 0.f;
2021-11-30 21:29:18 -06:00
}
2022-01-19 16:43:21 -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
}