This commit is contained in:
rnlf
2017-01-22 20:23:54 +01:00
parent b954b0ff2d
commit 3c4cb195e0
8 changed files with 82 additions and 36 deletions

View File

@@ -1,9 +1,17 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 <string.h>
#include <dos.h> #include <dos.h>
#include <stdbool.h> #include <stdbool.h>
#include "mixer.h" #include "mixer.h"
#include "soundblaster.h" #include "soundblaster.h"
// Configure me!
#define MIXER_MAX_SOURCES 8 #define MIXER_MAX_SOURCES 8
@@ -14,9 +22,9 @@ typedef struct {
static mixed_sound_t sources[MIXER_MAX_SOURCES]; static mixed_sound_t sources[MIXER_MAX_SOURCES];
static int activeSources = 0; static int activeSources = 0;
static int16_t data[SOUNDBLASTER_SAMPLES_PER_BUFFER] = {0}; static int16_t data[SOUNDBLASTER_SAMPLES_PER_BUFFER] = {0};
static bool canmix = true; static bool canmix = true;
void mixer_init(void) { void mixer_init(void) {
@@ -59,15 +67,16 @@ static inline int16_t mix(int32_t a, int32_t b) {
void mixer_mix(void) { void mixer_mix(void) {
if(!canmix) if(!canmix) {
return; return;
}
memset(data, 0, SOUNDBLASTER_SAMPLES_PER_BUFFER); memset(data, 0, SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(int16_t));
for(int i = 0; i < activeSources; ++i) { for(int i = 0; i < activeSources; ++i) {
mixed_sound_t *snd = sources + i; mixed_sound_t *snd = sources + i;
int len = snd->source->sampleCount; int len = snd->source->sampleCount;
int16_t const* sourceBuf = snd->source->samples; int16_t const* sourceBuf = snd->source->samples + snd->offset;
if(len > SOUNDBLASTER_SAMPLES_PER_BUFFER) { if(len > SOUNDBLASTER_SAMPLES_PER_BUFFER) {
len = SOUNDBLASTER_SAMPLES_PER_BUFFER; len = SOUNDBLASTER_SAMPLES_PER_BUFFER;
@@ -80,7 +89,6 @@ void mixer_mix(void) {
snd->offset += len; snd->offset += len;
} }
for(int i = activeSources-1; i >= 0; --i) { for(int i = activeSources-1; i >= 0; --i) {
mixed_sound_t *snd = sources + i; mixed_sound_t *snd = sources + i;
if(snd->offset == snd->source->sampleCount) { if(snd->offset == snd->source->sampleCount) {

View File

@@ -1,11 +1,20 @@
#pragma once /**
* Copyright (c) 2017 rnlf
*
* 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 <stdint.h>
#include "source.h" #include "source.h"
void mixer_init(void); void mixer_init(void);
void mixer_deinit(void); void mixer_deinit(void);
int16_t const* mixer_getNextBlock(void); int16_t const* mixer_getNextBlock(void);
void mixer_play(source_t const *source); void mixer_play(source_t const *source);
void mixer_mix(void); void mixer_mix(void);
#endif

View File

@@ -1,4 +1,9 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 "mixer.h"
#include "luaobj.h" #include "luaobj.h"
@@ -9,8 +14,10 @@ int l_sound_mix(lua_State *L) {
return 0; return 0;
} }
int l_source_new(lua_State *L); int l_source_new(lua_State *L);
int luaopen_sound(lua_State *L) { int luaopen_sound(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "mix", l_sound_mix }, { "mix", l_sound_mix },

View File

@@ -1,4 +1,9 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 "luaobj.h"
#include "source.h" #include "source.h"

View File

@@ -1,3 +1,10 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
@@ -6,21 +13,13 @@
#include <dpmi.h> #include <dpmi.h>
#include <go32.h> #include <go32.h>
#include <sys/nearptr.h> #include <sys/nearptr.h>
#include "soundblaster.h" #include "soundblaster.h"
#define BYTE(val, byte) (((val) >> ((byte) * 8)) & 0xFF) #define BYTE(val, byte) (((val) >> ((byte) * 8)) & 0xFF)
static uint16_t *sampleBuffer;
static int sampleBufferSelector;
static uint16_t baseAddress;
static uint16_t irq;
static uint16_t dmaChannel;
int isrcount = 0;
#define SAMPLE_BUFFER_SIZE (SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(uint16_t) * 2) #define SAMPLE_BUFFER_SIZE (SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(uint16_t) * 2)
// SB16 port offsets // SB16
#define BLASTER_RESET_PORT 0x6 #define BLASTER_RESET_PORT 0x6
#define BLASTER_READ_PORT 0xA #define BLASTER_READ_PORT 0xA
#define BLASTER_WRITE_PORT 0xC #define BLASTER_WRITE_PORT 0xC
@@ -34,9 +33,6 @@ int isrcount = 0;
#define BLASTER_READ_BUFFER_STATUS_AVAIL 0x80 #define BLASTER_READ_BUFFER_STATUS_AVAIL 0x80
#define BLASTER_WRITE_BUFFER_STATUS_UNAVAIL 0x80 #define BLASTER_WRITE_BUFFER_STATUS_UNAVAIL 0x80
#define BLASTER_READY_BYTE 0xAA #define BLASTER_READY_BYTE 0xAA
// SB16 command constants
#define BLASTER_SET_OUTPUT_SAMPLING_RATE 0x41 #define BLASTER_SET_OUTPUT_SAMPLING_RATE 0x41
#define BLASTER_PROGRAM_16BIT_IO_CMD 0xB0 #define BLASTER_PROGRAM_16BIT_IO_CMD 0xB0
#define BLASTER_PROGRAM_16BIT_FLAG_FIFO 0x02 #define BLASTER_PROGRAM_16BIT_FLAG_FIFO 0x02
@@ -59,7 +55,7 @@ int isrcount = 0;
#define PIC_IRQ8F_MAP 0x70 #define PIC_IRQ8F_MAP 0x70
// DMA Data // DMA
#define DMA_DIRECTION_READ_FROM_MEMORY 0x04 #define DMA_DIRECTION_READ_FROM_MEMORY 0x04
#define DMA_TRANSFER_MODE_BLOCK 0x80 #define DMA_TRANSFER_MODE_BLOCK 0x80
@@ -81,13 +77,16 @@ static const struct {
{ 0xC8, 0xCA, 0xD4, 0xD6, 0xD8, 0x89 }, { 0xC8, 0xCA, 0xD4, 0xD6, 0xD8, 0x89 },
{ 0xCC, 0xCE, 0xD4, 0xD6, 0xD8, 0x8A } { 0xCC, 0xCE, 0xD4, 0xD6, 0xD8, 0x8A }
}; };
int stopDma = 0;
// ISR data static int stopDma = 0;
int isrInstalled = 0; static uint16_t *sampleBuffer;
static int sampleBufferSelector;
static uint16_t baseAddress;
static uint16_t irq;
static uint16_t dmaChannel;
static bool isrInstalled = false;
static int writePage = 0;
static _go32_dpmi_seginfo oldBlasterHandler, newBlasterHandler; static _go32_dpmi_seginfo oldBlasterHandler, newBlasterHandler;
int writePage = 0;
static soundblaster_getSampleProc getSamples; static soundblaster_getSampleProc getSamples;
@@ -128,7 +127,6 @@ static void soundblasterISR(void) {
BLASTER_MIXER_INTERRUPT_STATUS); BLASTER_MIXER_INTERRUPT_STATUS);
uint8_t status = inportb(baseAddress + BLASTER_MIXER_IN_PORT); uint8_t status = inportb(baseAddress + BLASTER_MIXER_IN_PORT);
isrcount++;
if(status & BLASTER_16BIT_INTERRUPT) { if(status & BLASTER_16BIT_INTERRUPT) {
if(stopDma == 1) { if(stopDma == 1) {
writeDSP(BLASTER_EXIT_AUTO_DMA); writeDSP(BLASTER_EXIT_AUTO_DMA);
@@ -157,7 +155,6 @@ static void setBlasterISR(void) {
? PIC_IRQ07_MAP ? PIC_IRQ07_MAP
: PIC_IRQ8F_MAP; : PIC_IRQ8F_MAP;
// Wrap and install ISR
_go32_dpmi_get_protected_mode_interrupt_vector(interruptVector, _go32_dpmi_get_protected_mode_interrupt_vector(interruptVector,
&oldBlasterHandler); &oldBlasterHandler);
@@ -165,7 +162,7 @@ static void setBlasterISR(void) {
newBlasterHandler.pm_selector = _go32_my_cs(); newBlasterHandler.pm_selector = _go32_my_cs();
_go32_dpmi_chain_protected_mode_interrupt_vector(interruptVector, &newBlasterHandler); _go32_dpmi_chain_protected_mode_interrupt_vector(interruptVector, &newBlasterHandler);
// PIC setup: unmask SB IRQ // PIC: unmask SB IRQ
if(irq < 8) { if(irq < 8) {
uint8_t irqmask = inportb(PIC1_DATA); uint8_t irqmask = inportb(PIC1_DATA);
outportb(PIC1_DATA, irqmask & ~(1<<irq)); outportb(PIC1_DATA, irqmask & ~(1<<irq));
@@ -174,7 +171,7 @@ static void setBlasterISR(void) {
outportb(PIC2_DATA, irqmask & ~(1<<(irq-8))); outportb(PIC2_DATA, irqmask & ~(1<<(irq-8)));
} }
isrInstalled = 1; isrInstalled = true;
} }
@@ -347,13 +344,13 @@ static void deallocSampleBuffer(void) {
static void resetBlasterISR(void) { static void resetBlasterISR(void) {
if(isrInstalled == 1) { if(isrInstalled) {
uint16_t interruptVector = irq + irq + (irq < 8) uint16_t interruptVector = irq + irq + (irq < 8)
? PIC_IRQ07_MAP ? PIC_IRQ07_MAP
: PIC_IRQ8F_MAP; : PIC_IRQ8F_MAP;
_go32_dpmi_set_protected_mode_interrupt_vector(interruptVector, &oldBlasterHandler); _go32_dpmi_set_protected_mode_interrupt_vector(interruptVector, &oldBlasterHandler);
isrInstalled = 0; isrInstalled = false;
} }
} }

View File

@@ -1,3 +1,10 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 SOUNDBLASTER_H #ifndef SOUNDBLASTER_H
#define SOUNDBLASTER_H #define SOUNDBLASTER_H

View File

@@ -1,3 +1,10 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>

View File

@@ -1,3 +1,10 @@
/**
* Copyright (c) 2017 rnlf
*
* 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 #ifndef SOURCE_H
#define SOURCE_H #define SOURCE_H
@@ -12,5 +19,4 @@ int source_initSilence(source_t *self, int samples);
char const* source_init(source_t *self, char const* filename); char const* source_init(source_t *self, char const* filename);
void source_deinit(source_t *self); void source_deinit(source_t *self);
#endif #endif