From 0502eead9a85b477e0b569e12e9c44cd24ec88df Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Thu, 2 Apr 2020 12:23:03 +0200 Subject: [PATCH] Support for playing music. --- emu/Makefile | 4 +-- emu/apr.c | 1 + emu/main_panel.c | 2 ++ emu/music.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ emu/pdp6.h | 3 ++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 emu/music.c diff --git a/emu/Makefile b/emu/Makefile index 37b9d06..f91e745 100644 --- a/emu/Makefile +++ b/emu/Makefile @@ -12,8 +12,8 @@ LIBS=-lpthread -lm SDLLIBS=`sdl2-config --libs` `pkg-config SDL2_image --libs` -pdp6: main_panel.c dis340.c chargen.inc joy.c $(SRC) $(H) - $(CC) -o $@ $(CFLAGS) $(SDLFLAGS) main_panel.c dis340.c joy.c $(SRC) $(LIBS) $(SDLLIBS) +pdp6: main_panel.c dis340.c chargen.inc joy.c music.c $(SRC) $(H) + $(CC) -o $@ $(CFLAGS) $(SDLFLAGS) main_panel.c dis340.c joy.c music.c $(SRC) $(LIBS) $(SDLLIBS) pdp6_s: main_serial.c $(SRC) $(H) $(CC) -o $@ $(CFLAGS) main_serial.c $(SRC) $(LIBS) diff --git a/emu/apr.c b/emu/apr.c index c0e191d..39617d2 100644 --- a/emu/apr.c +++ b/emu/apr.c @@ -3109,6 +3109,7 @@ defpulse(mi_fm_mb) { // 7-7 apr->mi |= apr->c.mb; + music_sample(apr->mi); } defpulse(mi_clr) diff --git a/emu/main_panel.c b/emu/main_panel.c index 253feaa..9fe8b82 100644 --- a/emu/main_panel.c +++ b/emu/main_panel.c @@ -1259,6 +1259,8 @@ void main340(void); if(apr == nil || tty == nil || ptr == nil || ptp == nil) err("need APR, TTY, PTR and PTP"); + music_init(apr); + while(awaitinit); cmdchans[0] = chancreate(sizeof(char*), 1); diff --git a/emu/music.c b/emu/music.c new file mode 100644 index 0000000..c4a20ac --- /dev/null +++ b/emu/music.c @@ -0,0 +1,72 @@ +#include "pdp6.h" +#include + +/* Number of samples in audio buffer. */ +#define AUDIO_SAMPLES (4*4096) +/* Number of samples in MI buffer. */ +#define MI_SAMPLES (100*1024) + +static Uint8 buffer[MI_SAMPLES]; +static Uint8 audio[2*AUDIO_SAMPLES]; + +int samples = 0; +int refill = 1; + +void music_sample(word mi) +{ + Uint8 x = 0; + int i; + if(samples == MI_SAMPLES) + return; + for(i = 0; i < 6; i++) { + if(mi & (1 << i)) + x+= 40; + } + buffer[samples++] = x; + + if(refill) { + int i, j; + fprintf (stderr, "[%d]", samples); + for(i = 0; i < 2*AUDIO_SAMPLES; i++) { + j = (int)((float)i * (float)MI_SAMPLES / (float)(2*AUDIO_SAMPLES) + .5); + audio[i] = buffer[j]; + } + samples = 0; + refill = 0; + } +} + +static void callback(void *data, Uint8 *stream, int len) +{ + if (refill) + memset(stream, 0, len); + else + memcpy(stream, audio, len); + refill = 1; +} + +void music_init(Apr *apr) +{ + SDL_AudioSpec want, have; + SDL_AudioDeviceID dev; + + SDL_memset(&want, 0, sizeof want); + want.freq = 48000; + want.format = AUDIO_U8; + want.channels = 1; + want.samples = AUDIO_SAMPLES; + want.callback = callback; + want.userdata = apr; + + dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE); + if (dev == 0) + SDL_Log("Failed to open audio: %s", SDL_GetError()); + else { + if (have.format != want.format) + SDL_Log("We didn't get Float32 audio format."); + fprintf(stderr, "Frequency: %d\n", have.freq); + fprintf(stderr, "Channels: %d\n", have.channels); + fprintf(stderr, "Samples: %d\n", have.samples); + SDL_PauseAudioDevice(dev, 0); + } +} diff --git a/emu/pdp6.h b/emu/pdp6.h index 0a42210..6891710 100644 --- a/emu/pdp6.h +++ b/emu/pdp6.h @@ -704,3 +704,6 @@ Device *makenetcons(int argc, char *argv[]); void writeconsreg(Apr *apr, u32 addr, u32 data); u32 readconsreg(Apr *apr, u32 addr); + +void music_init(Apr *apr); +void music_sample(word mi);