Audio and video works
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "log.h"
|
||||
#include "texture.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
struct mShader *vid_shader;
|
||||
|
||||
@@ -31,7 +32,7 @@ static void render_audio(plm_t * mpeg, plm_samples_t * samples, void *user)
|
||||
{
|
||||
struct datastream *ds = user;
|
||||
int size = sizeof(float) * samples->count * 2;
|
||||
play_raw(ds->audio_device, samples->interleaved, size);
|
||||
play_raw(ds->audio_device, samples->interleaved, samples->count * 2);
|
||||
}
|
||||
|
||||
struct Texture *ds_maketexture(struct datastream *ds)
|
||||
@@ -54,10 +55,12 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
||||
YughLog(0, 0, "Couldn't open %s", video);
|
||||
}
|
||||
|
||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, duration: %f",
|
||||
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_duration(ds->plm)
|
||||
plm_get_samplerate(ds->plm),
|
||||
plm_get_num_audio_streams(ds->plm),
|
||||
plm_get_duration(ds->plm)
|
||||
);
|
||||
|
||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||
@@ -68,7 +71,7 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
||||
plm_set_audio_stream(ds->plm, 0);
|
||||
|
||||
// Adjust the audio lead time according to the audio_spec buffer size
|
||||
//plm_set_audio_lead_time(plm, (double)audio_spec.samples / (double)samplerate);
|
||||
//plm_set_audio_lead_time(ds->plm, 4096/48000);
|
||||
|
||||
ds->playing = true;
|
||||
}
|
||||
|
||||
12374
source/engine/dr_flac.h
Normal file
12374
source/engine/dr_flac.h
Normal file
File diff suppressed because it is too large
Load Diff
4785
source/engine/dr_mp3.h
Normal file
4785
source/engine/dr_mp3.h
Normal file
File diff suppressed because it is too large
Load Diff
8305
source/engine/dr_wav.h
Normal file
8305
source/engine/dr_wav.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,12 +6,12 @@
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include <stb_truetype.h>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#define PL_MPEG_IMPLEMENTATION
|
||||
#include <pl_mpeg.h>
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include <miniaudio.h>
|
||||
|
||||
#ifdef EDITOR
|
||||
#include "editor.h"
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,13 +6,15 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "vec.h"
|
||||
#include <ftw.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define __USE_XOPEN_EXTENDED 1
|
||||
#include <ftw.h>
|
||||
|
||||
char *DATA_PATH = NULL;
|
||||
char *PREF_PATH = NULL;
|
||||
|
||||
|
||||
@@ -2,46 +2,222 @@
|
||||
#include "resources.h"
|
||||
#include <stdlib.h>
|
||||
#include "log.h"
|
||||
#include "string.h"
|
||||
|
||||
ma_engine engine;
|
||||
#define TSF_IMPLEMENTATION
|
||||
#include "tsf.h"
|
||||
|
||||
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#include "dr_wav.h"
|
||||
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#include "dr_mp3.h"
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
//ma_engine engine;
|
||||
|
||||
const char *audioDriver;
|
||||
|
||||
struct sound *mus_cur;
|
||||
ma_sound_group mus_grp;
|
||||
//ma_sound_group mus_grp;
|
||||
|
||||
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
typedef struct
|
||||
{
|
||||
printf("audio cb\n");
|
||||
// In playback mode copy data to pOutput. In capture mode read data from pInput. In full-duplex mode, both
|
||||
// pOutput and pInput will be valid and you can move data from pInput into pOutput. Never process more than
|
||||
// frameCount frames.
|
||||
ma_engine_read_pcm_frames(&engine, pOutput, frameCount, NULL);
|
||||
float left_phase;
|
||||
float right_phase;
|
||||
} paTestData;
|
||||
|
||||
#define SOUNDBUF 163864
|
||||
|
||||
float samplebuffer[SOUNDBUF];
|
||||
float *tail;
|
||||
float *head;
|
||||
|
||||
short HalfSecond[22400];
|
||||
short *shorthead;
|
||||
|
||||
|
||||
unsigned int ch;
|
||||
unsigned int srate;
|
||||
drwav_uint64 curcmf = 0;
|
||||
drwav_uint64 totalpcmf;
|
||||
float *psamps;
|
||||
|
||||
drmp3 mp3;
|
||||
|
||||
static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
|
||||
{
|
||||
/* Cast data passed through stream to our structure. */
|
||||
float *out = (float*)outputBuffer;
|
||||
|
||||
int f = 0;
|
||||
|
||||
/*
|
||||
while (curcmf < totalpcmf && f <= framesPerBuffer) {
|
||||
*(out++) = psamps[curcmf++];
|
||||
curcmf++;
|
||||
*(out++) = psamps[curcmf++];
|
||||
curcmf++;
|
||||
f++;
|
||||
}
|
||||
*/
|
||||
//printf("Now is %lu of %lu.\n", curcmf, totalpcmf);
|
||||
|
||||
/*
|
||||
while (f < framesPerBuffer && shorthead != &HalfSecond[22400]) {
|
||||
*(out++) = (float)*(shorthead++) / 32767.f;
|
||||
}
|
||||
*/
|
||||
|
||||
for (int i = 0; i < framesPerBuffer; i++) {
|
||||
float a[2] = {0.f, 0.f};
|
||||
drmp3_uint64 fraead = drmp3_read_pcm_frames_f32(&mp3, 1, a);
|
||||
|
||||
|
||||
if (tail != head)
|
||||
a[0] += *(tail++) * 5;
|
||||
|
||||
if (tail == samplebuffer + SOUNDBUF-1) tail = samplebuffer;
|
||||
|
||||
if (tail != head)
|
||||
a[1] += *(tail++) * 5;
|
||||
|
||||
if (tail == samplebuffer + SOUNDBUF-1) tail = samplebuffer;
|
||||
|
||||
|
||||
*(out++) = a[0];
|
||||
*(out++) = a[1];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
while (tail != head && f++ < framesPerBuffer) {
|
||||
*(out++) = *(tail++);
|
||||
|
||||
if (tail == (samplebuffer+SOUNDBUF-1))
|
||||
tail = samplebuffer;
|
||||
|
||||
*(out++) = *(tail++);
|
||||
|
||||
if (tail == (samplebuffer+SOUNDBUF-1))
|
||||
tail = samplebuffer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
while (f++ < framesPerBuffer) {
|
||||
drmp3_uint64 framesread = drmp3_read_pcm_frames_f32(&mp3, 1, out);
|
||||
out += 2;
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void check_pa_err(PaError e)
|
||||
{
|
||||
if (e != paNoError) {
|
||||
YughError("PA Error: %s", Pa_GetErrorText(e));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static paTestData data;
|
||||
static PaStream *stream_def;
|
||||
|
||||
void sound_init()
|
||||
{
|
||||
/*
|
||||
tsf *sf = tsf_load_filename("sounds/test.sf2");
|
||||
tsf_set_output(sf, TSF_STEREO_INTERLEAVED, 48000, 0);
|
||||
tsf_note_on(sf, 0, 60, 1.f);
|
||||
|
||||
tsf_render_short(sf, HalfSecond, 22400, 0);
|
||||
*/
|
||||
|
||||
drwav wav;
|
||||
if (!drwav_init_file(&wav, "sounds/alert.wav", NULL)) {
|
||||
YughError("Could not open wav.",0);
|
||||
}
|
||||
|
||||
//drwav_int32 *wavdec = malloc(wav.totalPCMFrameCount * wav.channels * sizeof(drwav_int32));
|
||||
//size_t samps = drwav_read_pcm_frames_s32(&wav, wav.totalPCMFrameCount, wavdec);
|
||||
|
||||
|
||||
ma_device_config cnf = ma_device_config_init(ma_device_type_playback);
|
||||
psamps = drwav_open_file_and_read_pcm_frames_f32("sounds/alert.wav", &ch, &srate, &totalpcmf, NULL);
|
||||
|
||||
printf("WAV is: %i channels, %i samplerate, %l frames.\n", ch, srate, totalpcmf);
|
||||
|
||||
|
||||
if (!drmp3_init_file(&mp3, "sounds/circus.mp3", NULL)) {
|
||||
YughError("Could not open mp3.",0);
|
||||
}
|
||||
|
||||
printf("CIrcus mp3 channels: %ui, samplerate: %ui\n", mp3.channels, mp3.sampleRate);
|
||||
|
||||
|
||||
PaError err = Pa_Initialize();
|
||||
check_pa_err(err);
|
||||
head = tail = samplebuffer;
|
||||
|
||||
int numDevices = Pa_GetDeviceCount();
|
||||
const PaDeviceInfo *deviceInfo;
|
||||
|
||||
for (int i = 0; i < numDevices; i++) {
|
||||
deviceInfo = Pa_GetDeviceInfo(i);
|
||||
|
||||
//printf("Device %i: channels %i, sample rate %f, name %s\n", i, deviceInfo->maxOutputChannels, deviceInfo->defaultSampleRate, deviceInfo->name);
|
||||
}
|
||||
|
||||
PaStreamParameters outparams;
|
||||
|
||||
|
||||
|
||||
outparams.channelCount = 2;
|
||||
outparams.device = 6;
|
||||
outparams.sampleFormat = paFloat32;
|
||||
outparams.suggestedLatency = Pa_GetDeviceInfo(outparams.device)->defaultLowOutputLatency;
|
||||
outparams.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(&stream_def, NULL, &outparams, 48000, 4096, paNoFlag, patestCallback, &data);
|
||||
check_pa_err(err);
|
||||
|
||||
err = Pa_StartStream(stream_def);
|
||||
check_pa_err(err);
|
||||
|
||||
//Pa_Sleep(1000);
|
||||
|
||||
//check_pa_err(Pa_StopStream(stream));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
ma_result result;
|
||||
ma_device device;
|
||||
ma_device_config cnf;
|
||||
|
||||
cnf = ma_device_config_init(ma_device_type_playback);
|
||||
cnf.playback.format = ma_format_f32;
|
||||
cnf.playback.channels = 2;
|
||||
cnf.sampleRate = 48000;
|
||||
cnf.dataCallback = data_callback;
|
||||
cnf.pUserData = mus_cur;
|
||||
|
||||
ma_device device;
|
||||
if (ma_device_init(NULL, &cnf, &device) != MA_SUCCESS) {
|
||||
result = ma_device_init(NULL, &cnf, &device);
|
||||
if (result != MA_SUCCESS) {
|
||||
YughError("Did not initialize audio playback!!",0);
|
||||
}
|
||||
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
result = ma_device_start(&device);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
ma_engine_config enginecnf = ma_engine_config_init();
|
||||
enginecnf.pDevice = &device;
|
||||
|
||||
@@ -52,7 +228,7 @@ void sound_init()
|
||||
}
|
||||
|
||||
ma_sound_group_init(&engine, 0, NULL, &mus_grp);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
void audio_open(const char *device)
|
||||
@@ -67,20 +243,22 @@ void audio_close()
|
||||
|
||||
struct sound *make_sound(const char *wav)
|
||||
{
|
||||
|
||||
struct sound *new = calloc(1, sizeof(struct sound));
|
||||
ma_result res = ma_sound_init_from_file(&engine, wav, 0, NULL, NULL, &new->sound);
|
||||
/* ma_result res = ma_sound_init_from_file(&engine, wav, 0, NULL, NULL, &new->sound);
|
||||
|
||||
if (res != MA_SUCCESS) {
|
||||
printf("HONO!!!!");
|
||||
}
|
||||
|
||||
*/
|
||||
return new;
|
||||
}
|
||||
|
||||
struct sound *make_music(const char *ogg)
|
||||
{
|
||||
|
||||
struct sound *sound = calloc(1, sizeof(struct sound));
|
||||
ma_result res = ma_sound_init_from_file(&engine, ogg, 0, NULL, &mus_grp, &sound->sound);
|
||||
// ma_result res = ma_sound_init_from_file(&engine, ogg, 0, NULL, &mus_grp, &sound->sound);
|
||||
|
||||
return sound;
|
||||
}
|
||||
@@ -88,15 +266,15 @@ struct sound *make_music(const char *ogg)
|
||||
void play_sound(struct sound *sound)
|
||||
{
|
||||
//ma_sound_set_volume(&sound->sound, (float)sound->volume/127);
|
||||
ma_sound_start(&sound->sound);
|
||||
sound->state = MUS_PLAY;
|
||||
// ma_sound_start(&sound->sound);
|
||||
// sound->state = MUS_PLAY;
|
||||
}
|
||||
|
||||
void play_music(struct sound *music)
|
||||
{
|
||||
ma_sound_start(&music->sound);
|
||||
music->state = MUS_PLAY;
|
||||
mus_cur = music;
|
||||
//ma_sound_start(&music->sound);
|
||||
//music->state = MUS_PLAY;
|
||||
// mus_cur = music;
|
||||
}
|
||||
|
||||
void music_set(struct sound *music)
|
||||
@@ -106,35 +284,37 @@ void music_set(struct sound *music)
|
||||
|
||||
void music_volume(unsigned char vol)
|
||||
{
|
||||
ma_sound_group_set_volume(&mus_grp, (float)vol/127);
|
||||
// ma_sound_group_set_volume(&mus_grp, (float)vol/127);
|
||||
}
|
||||
|
||||
int music_playing()
|
||||
{
|
||||
return ma_sound_is_playing(&mus_cur->sound);
|
||||
//return ma_sound_is_playing(&mus_cur->sound);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int music_paused()
|
||||
{
|
||||
return mus_cur->state == MUS_PAUSE;
|
||||
// return mus_cur->state == MUS_PAUSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void music_resume()
|
||||
{
|
||||
ma_sound_start(&mus_cur->sound);
|
||||
// ma_sound_start(&mus_cur->sound);
|
||||
}
|
||||
|
||||
void music_pause()
|
||||
{
|
||||
ma_sound_stop(&mus_cur->sound);
|
||||
mus_cur->state = MUS_PAUSE;
|
||||
//ma_sound_stop(&mus_cur->sound);
|
||||
//mus_cur->state = MUS_PAUSE;
|
||||
}
|
||||
|
||||
void music_stop()
|
||||
{
|
||||
ma_sound_stop(&mus_cur->sound);
|
||||
mus_cur->state = MUS_STOP;
|
||||
ma_sound_seek_to_pcm_frame(&mus_cur->sound, 0);
|
||||
// ma_sound_stop(&mus_cur->sound);
|
||||
// mus_cur->state = MUS_STOP;
|
||||
// ma_sound_seek_to_pcm_frame(&mus_cur->sound, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +325,14 @@ void audio_init()
|
||||
|
||||
void play_raw(int device, void *data, int size)
|
||||
{
|
||||
//SDL_QueueAudio(device, data, size);
|
||||
float *d = data;
|
||||
while (size >= 0) {
|
||||
*(head++) = *(d++);
|
||||
|
||||
if (head == (samplebuffer+SOUNDBUF-1)) head = samplebuffer;
|
||||
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
void close_audio_device(int device)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#include "miniaudio.h"
|
||||
|
||||
|
||||
|
||||
struct Mix_Chunk {
|
||||
int i;
|
||||
};
|
||||
@@ -20,7 +16,7 @@ enum MUS {
|
||||
};
|
||||
|
||||
struct sound {
|
||||
ma_sound sound;
|
||||
int sound;
|
||||
enum MUS state;
|
||||
unsigned char volume;
|
||||
};
|
||||
|
||||
@@ -51,7 +51,7 @@ struct Texture {
|
||||
struct TexAnim anim;
|
||||
};
|
||||
|
||||
struct Texture *tex_pullfromfile(const char *path);
|
||||
struct Texture *texture_pullfromfile(const char *path);
|
||||
struct Texture *texture_loadfromfile(const char *path);
|
||||
void tex_gpu_load(struct Texture *tex);
|
||||
void tex_gpu_reload(struct Texture *tex);
|
||||
|
||||
@@ -87,6 +87,8 @@ void *vec_find(struct vec *v, int (*valid)(void *a, void *data), void *data)
|
||||
if (valid(vec_p(v, i), data))
|
||||
return vec_p(v, i);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *vec_insert(struct vec *vec, void *data, int n)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <vec.h>
|
||||
#include "input.h"
|
||||
|
||||
static struct mSDLWindow *mainwin;
|
||||
struct mSDLWindow *mainwin;
|
||||
|
||||
static struct vec windows;
|
||||
struct Texture *icon = NULL;
|
||||
|
||||
Reference in New Issue
Block a user