Removed: wav, source, mixer, love.sound, love.source
This commit is contained in:
@@ -104,7 +104,6 @@ function love.run()
|
|||||||
love.graphics.clear()
|
love.graphics.clear()
|
||||||
if love.draw then love.draw() end
|
if love.draw then love.draw() end
|
||||||
love.graphics.present()
|
love.graphics.present()
|
||||||
love.sound.mix()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2017 rxi
|
* Copyright (c) 2017 rxi
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
* This library is free software; you can redistribute it and/or modify it
|
||||||
@@ -25,10 +25,9 @@ typedef struct {
|
|||||||
#define LUAOBJ_TYPE_IMAGE (1 << 0)
|
#define LUAOBJ_TYPE_IMAGE (1 << 0)
|
||||||
#define LUAOBJ_TYPE_QUAD (1 << 1)
|
#define LUAOBJ_TYPE_QUAD (1 << 1)
|
||||||
#define LUAOBJ_TYPE_FONT (1 << 2)
|
#define LUAOBJ_TYPE_FONT (1 << 2)
|
||||||
#define LUAOBJ_TYPE_SOURCE (1 << 3)
|
|
||||||
|
|
||||||
|
|
||||||
int luaobj_newclass(lua_State *L, const char *name, const char *extends,
|
int luaobj_newclass(lua_State *L, const char *name, const char *extends,
|
||||||
int (*constructor)(lua_State*), luaL_Reg* reg);
|
int (*constructor)(lua_State*), luaL_Reg* reg);
|
||||||
void luaobj_setclass(lua_State *L, uint32_t type, char *name);
|
void luaobj_setclass(lua_State *L, uint32_t type, char *name);
|
||||||
void *luaobj_newudata(lua_State *L, int size);
|
void *luaobj_newudata(lua_State *L, int size);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "soundblaster.h"
|
#include "soundblaster.h"
|
||||||
#include "mixer.h"
|
|
||||||
|
|
||||||
|
|
||||||
static lua_State *L;
|
static lua_State *L;
|
||||||
@@ -58,7 +57,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* Init everything */
|
/* Init everything */
|
||||||
atexit(deinit);
|
atexit(deinit);
|
||||||
soundblaster_init(mixer_getNextBlock);
|
// soundblaster_init(mixer_getNextBlock);
|
||||||
vga_init();
|
vga_init();
|
||||||
palette_init();
|
palette_init();
|
||||||
keyboard_init();
|
keyboard_init();
|
||||||
|
|||||||
97
src/mixer.c
97
src/mixer.c
@@ -1,97 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <dos.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "mixer.h"
|
|
||||||
#include "soundblaster.h"
|
|
||||||
|
|
||||||
// Configure me!
|
|
||||||
#define MIXER_MAX_SOURCES 8
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int offset;
|
|
||||||
source_t const *source;
|
|
||||||
} mixed_sound_t;
|
|
||||||
|
|
||||||
|
|
||||||
static mixed_sound_t sources[MIXER_MAX_SOURCES];
|
|
||||||
static int activeSources = 0;
|
|
||||||
static int16_t data[SOUNDBLASTER_SAMPLES_PER_BUFFER] = {0};
|
|
||||||
static bool canmix = true;
|
|
||||||
|
|
||||||
|
|
||||||
int16_t const * mixer_getNextBlock(void) {
|
|
||||||
canmix = true;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mixer_play(source_t const *source) {
|
|
||||||
if(activeSources == MIXER_MAX_SOURCES) {
|
|
||||||
// TODO Replace older source with new one instead?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < activeSources; ++i) {
|
|
||||||
if(sources[i].source == source) {
|
|
||||||
sources[i].offset = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sources[activeSources].offset = 0;
|
|
||||||
sources[activeSources].source = source;
|
|
||||||
++activeSources;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int16_t mix(int32_t a, int32_t b) {
|
|
||||||
int32_t res = a + b;
|
|
||||||
if(res > INT16_MAX)
|
|
||||||
res = INT16_MAX;
|
|
||||||
if(res < INT16_MIN)
|
|
||||||
res = INT16_MIN;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mixer_mix(void) {
|
|
||||||
if(!canmix) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(data, 0, SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(int16_t));
|
|
||||||
|
|
||||||
for(int i = 0; i < activeSources; ++i) {
|
|
||||||
mixed_sound_t *snd = sources + i;
|
|
||||||
int len = snd->source->sampleCount - snd->offset;
|
|
||||||
int16_t const* sourceBuf = snd->source->samples + snd->offset;
|
|
||||||
|
|
||||||
if(len > SOUNDBLASTER_SAMPLES_PER_BUFFER) {
|
|
||||||
len = SOUNDBLASTER_SAMPLES_PER_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int offset = 0; offset < len; ++offset) {
|
|
||||||
data[offset] = mix(data[offset], sourceBuf[offset]);
|
|
||||||
}
|
|
||||||
|
|
||||||
snd->offset += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = activeSources-1; i >= 0; --i) {
|
|
||||||
mixed_sound_t *snd = sources + i;
|
|
||||||
if(snd->offset == snd->source->sampleCount) {
|
|
||||||
*snd = sources[activeSources-1];
|
|
||||||
--activeSources;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
canmix = false;
|
|
||||||
}
|
|
||||||
18
src/mixer.h
18
src/mixer.h
@@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MIXER_H
|
|
||||||
#define MIXER_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "source.h"
|
|
||||||
|
|
||||||
int16_t const* mixer_getNextBlock(void);
|
|
||||||
void mixer_play(source_t const *source);
|
|
||||||
void mixer_mix(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -26,8 +26,6 @@ int luaopen_graphics(lua_State *L);
|
|||||||
int luaopen_timer(lua_State *L);
|
int luaopen_timer(lua_State *L);
|
||||||
int luaopen_keyboard(lua_State *L);
|
int luaopen_keyboard(lua_State *L);
|
||||||
int luaopen_mouse(lua_State *L);
|
int luaopen_mouse(lua_State *L);
|
||||||
int luaopen_sound(lua_State *L);
|
|
||||||
int luaopen_source(lua_State *L);
|
|
||||||
|
|
||||||
int luaopen_love(lua_State *L) {
|
int luaopen_love(lua_State *L) {
|
||||||
int i;
|
int i;
|
||||||
@@ -38,7 +36,6 @@ int luaopen_love(lua_State *L) {
|
|||||||
luaopen_image,
|
luaopen_image,
|
||||||
luaopen_quad,
|
luaopen_quad,
|
||||||
luaopen_font,
|
luaopen_font,
|
||||||
luaopen_source,
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
for (i = 0; classes[i]; i++) {
|
for (i = 0; classes[i]; i++) {
|
||||||
@@ -62,7 +59,6 @@ int luaopen_love(lua_State *L) {
|
|||||||
{ "timer", luaopen_timer },
|
{ "timer", luaopen_timer },
|
||||||
{ "keyboard", luaopen_keyboard },
|
{ "keyboard", luaopen_keyboard },
|
||||||
{ "mouse", luaopen_mouse },
|
{ "mouse", luaopen_mouse },
|
||||||
{ "sound", luaopen_sound },
|
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
for (i = 0; mods[i].name; i++) {
|
for (i = 0; mods[i].name; i++) {
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mixer.h"
|
|
||||||
#include "luaobj.h"
|
|
||||||
|
|
||||||
|
|
||||||
int l_sound_mix(lua_State *L) {
|
|
||||||
mixer_mix();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int l_source_new(lua_State *L);
|
|
||||||
|
|
||||||
|
|
||||||
int luaopen_sound(lua_State *L) {
|
|
||||||
luaL_Reg reg[] = {
|
|
||||||
{ "mix", l_sound_mix },
|
|
||||||
{ "newSource", l_source_new },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
luaL_newlib(L, reg);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "luaobj.h"
|
|
||||||
#include "source.h"
|
|
||||||
#include "mixer.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define CLASS_TYPE LUAOBJ_TYPE_SOURCE
|
|
||||||
#define CLASS_NAME "Source"
|
|
||||||
|
|
||||||
|
|
||||||
int l_source_new(lua_State *L) {
|
|
||||||
const char *filename = luaL_checkstring(L, 1);
|
|
||||||
|
|
||||||
source_t *self = luaobj_newudata(L, sizeof(*self));
|
|
||||||
luaobj_setclass(L, CLASS_TYPE, CLASS_NAME);
|
|
||||||
const char *err = source_init(self, filename);
|
|
||||||
if (err) luaL_error(L, err);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int l_source_gc(lua_State *L) {
|
|
||||||
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
|
|
||||||
source_deinit(self);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int l_source_play(lua_State *L) {
|
|
||||||
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
|
|
||||||
mixer_play(self);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int luaopen_source(lua_State *L) {
|
|
||||||
luaL_Reg reg[] = {
|
|
||||||
{ "new", l_source_new },
|
|
||||||
{ "__gc", l_source_gc },
|
|
||||||
{ "play", l_source_play },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
luaobj_newclass(L, CLASS_NAME, NULL, l_source_new, reg);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
60
src/source.c
60
src/source.c
@@ -1,60 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "source.h"
|
|
||||||
#include "filesystem.h"
|
|
||||||
#include "lib/dmt/dmt.h"
|
|
||||||
#include "wav.h"
|
|
||||||
|
|
||||||
|
|
||||||
char const* source_init(source_t *self, char const* filename) {
|
|
||||||
int fileSize;
|
|
||||||
void *waveData = filesystem_read(filename, &fileSize);
|
|
||||||
|
|
||||||
char const *err = NULL;
|
|
||||||
wav_t wav;
|
|
||||||
int res = wav_read(&wav, waveData, fileSize);
|
|
||||||
|
|
||||||
if(res != WAV_ESUCCESS) {
|
|
||||||
err = wav_strerror(res);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wav.bitdepth != 16) {
|
|
||||||
err = "Invalid Audio Format (only 16 Bit supported)";
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wav.samplerate != 22050) {
|
|
||||||
err = "Invalid Audio Format (only 22050Hz supported)";
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wav.channels != 1) {
|
|
||||||
err = "Invalid Audio Format (only mono supported)";
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->sampleCount = wav.length;
|
|
||||||
self->data = waveData;
|
|
||||||
self->samples = (int16_t*)wav.data;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
filesystem_free(waveData);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void source_deinit(source_t *self) {
|
|
||||||
filesystem_free(self->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
22
src/source.h
22
src/source.h
@@ -1,22 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2017 Florian Kesseler
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOURCE_H
|
|
||||||
#define SOURCE_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int sampleCount;
|
|
||||||
int16_t *samples;
|
|
||||||
void *data;
|
|
||||||
} source_t;
|
|
||||||
|
|
||||||
char const* source_init(source_t *self, char const* filename);
|
|
||||||
void source_deinit(source_t *self);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
84
src/wav.c
84
src/wav.c
@@ -1,84 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 rxi
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "wav.h"
|
|
||||||
|
|
||||||
typedef unsigned short Uint16;
|
|
||||||
typedef unsigned int Uint32;
|
|
||||||
|
|
||||||
|
|
||||||
static const char *findSubChunk(
|
|
||||||
const char *data, size_t len, const char *id, size_t *size
|
|
||||||
) {
|
|
||||||
/* TODO : Error handling on malformed wav file */
|
|
||||||
size_t idLen = strlen(id);
|
|
||||||
const char *p = data + 12;
|
|
||||||
next:
|
|
||||||
*size = *((Uint32*) (p + 4));
|
|
||||||
if (memcmp(p, id, idLen)) {
|
|
||||||
p += 8 + *size;
|
|
||||||
if (p > data + len) return NULL;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
return p + 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int wav_read(wav_t *w, const void *data, size_t len) {
|
|
||||||
int bitdepth, channels, samplerate, format;
|
|
||||||
size_t sz;
|
|
||||||
const char *p = data;
|
|
||||||
memset(w, 0, sizeof(*w));
|
|
||||||
/* Check header */
|
|
||||||
if (memcmp(p, "RIFF", 4) || memcmp(p + 8, "WAVE", 4)) {
|
|
||||||
return WAV_EBADHEADER;
|
|
||||||
}
|
|
||||||
/* Find fmt subchunk */
|
|
||||||
p = findSubChunk(data, len, "fmt", &sz);
|
|
||||||
if (!p) return WAV_ENOFMT;
|
|
||||||
/* Load fmt info */
|
|
||||||
format = *((Uint16*) (p));
|
|
||||||
channels = *((Uint16*) (p + 2));
|
|
||||||
samplerate = *((Uint32*) (p + 4));
|
|
||||||
bitdepth = *((Uint16*) (p + 14));
|
|
||||||
if (format != 1) {
|
|
||||||
return WAV_ENOSUPPORT;
|
|
||||||
}
|
|
||||||
if (channels == 0 || samplerate == 0 || bitdepth == 0) {
|
|
||||||
return WAV_EBADFMT;
|
|
||||||
}
|
|
||||||
/* Find data subchunk */
|
|
||||||
p = findSubChunk(data, len, "data", &sz);
|
|
||||||
if (!p) return WAV_ENODATA;
|
|
||||||
/* Init wav_t struct */
|
|
||||||
w->data = p;
|
|
||||||
w->samplerate = samplerate;
|
|
||||||
w->channels = channels;
|
|
||||||
w->length = (sz / (bitdepth / 8)) / channels;
|
|
||||||
w->bitdepth = bitdepth;
|
|
||||||
/* Done! */
|
|
||||||
return WAV_ESUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *wav_strerror(int err) {
|
|
||||||
switch (err) {
|
|
||||||
case WAV_ESUCCESS : return "success";
|
|
||||||
case WAV_EFAILURE : return "failure";
|
|
||||||
case WAV_EBADHEADER : return "bad header data";
|
|
||||||
case WAV_EBADFMT : return "bad fmt data";
|
|
||||||
case WAV_ENOFMT : return "missing 'fmt' subchunk";
|
|
||||||
case WAV_ENODATA : return "missing 'data' subchunk";
|
|
||||||
case WAV_ENOSUPPORT : return "unsupported format; "
|
|
||||||
"expected uncompressed PCM";
|
|
||||||
}
|
|
||||||
return "unknown error";
|
|
||||||
}
|
|
||||||
36
src/wav.h
36
src/wav.h
@@ -1,36 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 rxi
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the MIT license. See LICENSE for details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef WAV_H
|
|
||||||
#define WAV_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const void *data;
|
|
||||||
int bitdepth;
|
|
||||||
int samplerate;
|
|
||||||
int channels;
|
|
||||||
size_t length;
|
|
||||||
} wav_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
WAV_ESUCCESS = 0,
|
|
||||||
WAV_EFAILURE = -1,
|
|
||||||
WAV_EBADHEADER = -2,
|
|
||||||
WAV_EBADFMT = -3,
|
|
||||||
WAV_ENOFMT = -4,
|
|
||||||
WAV_ENODATA = -5,
|
|
||||||
WAV_ENOSUPPORT = -6
|
|
||||||
};
|
|
||||||
|
|
||||||
int wav_read(wav_t *w, const void *data, size_t len);
|
|
||||||
const char *wav_strerror(int err);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user