From 85f8e92973ca60968cfb844d2119b669ce610c2d Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 8 Feb 2007 23:19:53 +0000 Subject: [PATCH] audio improvement wip git-svn-id: file:///home/notaz/opt/svn/PicoDrive@33 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/sound/sound.c | 9 ++++++-- Pico/sound/ym2612.c | 25 ++++++++++++--------- Pico/sound/ym2612.h | 9 ++++---- Pico/sound/ym2612.s | 6 ++++- platform/gp2x/{940ctl_ym2612.c => 940ctl.c} | 24 +++++++++++++------- platform/gp2x/{940ctl_ym2612.h => 940ctl.h} | 1 + platform/gp2x/Makefile | 2 +- platform/gp2x/code940/940.c | 3 ++- platform/gp2x/code940/940shared.h | 1 + platform/gp2x/gp2x.c | 11 +++++++++ platform/gp2x/main.c | 3 +++ 11 files changed, 66 insertions(+), 28 deletions(-) rename platform/gp2x/{940ctl_ym2612.c => 940ctl.c} (93%) rename platform/gp2x/{940ctl_ym2612.h => 940ctl.h} (89%) diff --git a/Pico/sound/sound.c b/Pico/sound/sound.c index a9f2f68b..28e6dc45 100644 --- a/Pico/sound/sound.c +++ b/Pico/sound/sound.c @@ -227,6 +227,7 @@ void sound_clear(void) int sound_render(int offset, int length) { + int buf32_updated = 0; int *buf32 = PsndBuffer+offset; int stereo = (PicoOpt & 8) >> 3; // emulating CD && PCM option enabled && PCM chip on && have enabled channels @@ -248,11 +249,15 @@ int sound_render(int offset, int length) // Add in the stereo FM buffer if (PicoOpt & 1) - YM2612UpdateOne(buf32, length, stereo, 1); + buf32_updated = YM2612UpdateOne(buf32, length, stereo, 1); + +//printf("active_chs: %02x\n", buf32_updated); // CD: PCM sound - if (do_pcm) + if (do_pcm) { pcm_update(buf32, length, stereo); + //buf32_updated = 1; + } // CD: CDDA audio if ((PicoMCD & 1) && (PicoOpt & 0x800)) diff --git a/Pico/sound/ym2612.c b/Pico/sound/ym2612.c index 60d6c818..75d5ad32 100644 --- a/Pico/sound/ym2612.c +++ b/Pico/sound/ym2612.c @@ -841,7 +841,7 @@ typedef struct UINT32 eg_timer; UINT32 eg_timer_add; UINT32 pack; // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16] - UINT32 algo; /* 50 */ + UINT32 algo; /* 50: algo[3], was_update */ INT32 op1_out; } chan_rend_context; @@ -1077,6 +1077,7 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length) } else { buffer[scounter] += smp; } + ct->algo = 8; // algo is only used in asm, here only bit3 is used } /* update phase counters AFTER output calculations */ @@ -1091,7 +1092,7 @@ void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length) #endif -static void chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l +static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l { chan_rend_context ct; @@ -1193,6 +1194,8 @@ static void chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // fla CH->SLOT[SLOT3].phase = ct.phase3; CH->SLOT[SLOT4].phase = ct.phase4; CH->mem_value = ct.mem; + + return (ct.algo & 8) >> 3; // had output } /* update phase increment and envelope generator */ @@ -1587,6 +1590,7 @@ INT32 *ym2612_dacout; int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty) { int pan; + int active_chs = 0; // if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash if (is_buf_empty) memset32(buffer, 0, length<>2)); - chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)); - chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2); - - return 1; // buffer updated + // flags: stereo, lastchan, disabled, ?, pan_r, pan_l + active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0; + active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1; + active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )) << 2; + active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3; + active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4; + active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5; + + return active_chs; // 1 if buffer updated } diff --git a/Pico/sound/ym2612.h b/Pico/sound/ym2612.h index 033ba26e..20147ff3 100644 --- a/Pico/sound/ym2612.h +++ b/Pico/sound/ym2612.h @@ -162,7 +162,7 @@ void *YM2612GetRegs(void); #define YM2612PicoStateLoad YM2612PicoStateLoad_ #else /* GP2X specific */ -#include "../../platform/gp2x/940ctl_ym2612.h" +#include "../../platform/gp2x/940ctl.h" extern int PicoOpt; #define YM2612Init(baseclock,rate) { \ if (PicoOpt&0x200) YM2612Init_940(baseclock, rate); \ @@ -172,10 +172,9 @@ extern int PicoOpt; if (PicoOpt&0x200) YM2612ResetChip_940(); \ else YM2612ResetChip_(); \ } -#define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) { \ - if (PicoOpt&0x200) YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty); \ - else YM2612UpdateOne_(buffer, length, stereo, is_buf_empty); \ -} +#define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) \ + (PicoOpt&0x200) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \ + YM2612UpdateOne_(buffer, length, stereo, is_buf_empty); #define YM2612Write(a,v) \ (PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v) #define YM2612Read() \ diff --git a/Pico/sound/ym2612.s b/Pico/sound/ym2612.s index 0c630e50..efc31970 100644 --- a/Pico/sound/ym2612.s +++ b/Pico/sound/ym2612.s @@ -2,6 +2,8 @@ @ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble. @ - notaz, 2006 +@ vim:filetype=armasm + .equiv SLOT1, 0 .equiv SLOT2, 2 .equiv SLOT3, 1 @@ -725,7 +727,7 @@ upd_slot1: @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]) -@ r0-r2=scratch, r3=sin_tab/scratch, r4=(length<<8)|algo, r5=tl_tab/slot, +@ r0-r2=scratch, r3=sin_tab/scratch, r4=(length<<8)|unused[4],was_update,algo[3], r5=tl_tab/slot, @ r6-r7=vol_out[4], r8=eg_timer, r9=eg_timer_add[31:16], r10=op1_out, r11=buffer .global chan_render_loop @ chan_rend_context *ct, int *buffer, int length @@ -856,6 +858,7 @@ crl_algo_done: @ -- WRITE SAMPLE -- tst r0, r0 beq ctl_sample_skip + orr r4, r4, #8 @ have_output tst r12, #1 beq ctl_sample_mono @@ -908,6 +911,7 @@ crl_do_phase: crl_loop_end: str r8, [lr, #0x44] @ eg_timer str r12, [lr, #0x4c] @ pack (for lfo_ampm) + str r4, [lr, #0x50] @ was_update str r10, [lr, #0x54] @ op1_out ldmfd sp!, {r4-r11,pc} diff --git a/platform/gp2x/940ctl_ym2612.c b/platform/gp2x/940ctl.c similarity index 93% rename from platform/gp2x/940ctl_ym2612.c rename to platform/gp2x/940ctl.c index bd88c718..5c53761e 100644 --- a/platform/gp2x/940ctl_ym2612.c +++ b/platform/gp2x/940ctl.c @@ -333,6 +333,16 @@ void sharedmem_init(void) } +void sharedmem_deinit(void) +{ + munmap(shared_mem, 0x210000); + munmap(mp3_mem, MP3_SIZE_MAX); + shared_mem = mp3_mem = NULL; + shared_data = NULL; + shared_ctl = NULL; +} + + extern char **g_argv; /* none of the functions in this file should be called before this one */ @@ -433,19 +443,17 @@ void YM2612ResetChip_940(void) int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty) { int *ym_buf = shared_data->ym_buffer; + int ym_active_chs; //printf("YM2612UpdateOne_940()\n"); if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE); - // mix in ym buffer - if (is_buf_empty) memcpy32(buffer, ym_buf, length<ym_active_chs; -// for (len = length << stereo; len > 0; len--) -// { -// *dest_buf++ += *ym_buf++; -// } + // mix in ym buffer. is_buf_empty means nobody mixed there anything yet and it may contain trash + if (is_buf_empty && ym_active_chs) memcpy32(buffer, ym_buf, length<writebuffsel == 1) { shared_ctl->writebuff0[writebuff_ptr] = 0xffff; @@ -467,7 +475,7 @@ int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty) add_job_940(JOB940_YM2612UPDATEONE); - return 1; + return ym_active_chs; } diff --git a/platform/gp2x/940ctl_ym2612.h b/platform/gp2x/940ctl.h similarity index 89% rename from platform/gp2x/940ctl_ym2612.h rename to platform/gp2x/940ctl.h index 186a6dfb..95e9a071 100644 --- a/platform/gp2x/940ctl_ym2612.h +++ b/platform/gp2x/940ctl.h @@ -1,4 +1,5 @@ void sharedmem_init(void); +void sharedmem_deinit(void); void YM2612Init_940(int baseclock, int rate); void YM2612ResetChip_940(void); diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 5efe302e..d4de0ec9 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -34,7 +34,7 @@ OBJCOPY = $(CROSS)objcopy # frontend OBJS += main.o menu.o gp2x.o usbjoy.o emu.o squidgehack.o asmutils.o cpuctrl.o # 940 core control -OBJS += 940ctl_ym2612.o +OBJS += 940ctl.o # Pico OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Utils.o ../../Pico/Memory.o ../../Pico/Misc.o \ ../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o diff --git a/platform/gp2x/code940/940.c b/platform/gp2x/code940/940.c index b242603b..c37c80e0 100644 --- a/platform/gp2x/code940/940.c +++ b/platform/gp2x/code940/940.c @@ -112,7 +112,8 @@ void Main940(void) YM2612Write_(d >> 8, d); } - YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1); + shared_ctl->ym_active_chs = + YM2612UpdateOne_(ym_buffer, shared_ctl->length, shared_ctl->stereo, 1); break; } diff --git a/platform/gp2x/code940/940shared.h b/platform/gp2x/code940/940shared.h index 89531962..e4105d88 100644 --- a/platform/gp2x/code940/940shared.h +++ b/platform/gp2x/code940/940shared.h @@ -35,6 +35,7 @@ typedef struct int writebuffsel; /* which write buffer to use (from 940 side) */ UINT16 writebuff0[2048]; /* list of writes to ym2612, 1024 for savestates, 1024 extra */ UINT16 writebuff1[2048]; + int ym_active_chs; int mp3_len; /* data len of loaded mp3 */ int mp3_offs; /* current playback offset (just after last decoded frame) */ int mp3_buffsel; /* which output buffer to decode to */ diff --git a/platform/gp2x/gp2x.c b/platform/gp2x/gp2x.c index 18c5e48c..b02a6856 100644 --- a/platform/gp2x/gp2x.c +++ b/platform/gp2x/gp2x.c @@ -52,6 +52,7 @@ void *gp2x_screen; #define FRAMEBUFF_ADDR3 0x4000000-640*480*4 static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 }; +static unsigned short gp2x_screenaddr_old[4]; /* video stuff */ @@ -269,6 +270,11 @@ void gp2x_init(void) gp2x_screen = gp2x_screens[0]; screensel = 0; + gp2x_screenaddr_old[0] = gp2x_memregs[0x290E>>1]; + gp2x_screenaddr_old[1] = gp2x_memregs[0x2910>>1]; + gp2x_screenaddr_old[2] = gp2x_memregs[0x2912>>1]; + gp2x_screenaddr_old[3] = gp2x_memregs[0x2914>>1]; + // snd mixerdev = open("/dev/mixer", O_RDWR); if (mixerdev == -1) @@ -288,6 +294,11 @@ void gp2x_deinit(void) Pause940(1); gp2x_video_changemode(15); + gp2x_memregs[0x290E>>1] = gp2x_screenaddr_old[0]; + gp2x_memregs[0x2910>>1] = gp2x_screenaddr_old[1]; + gp2x_memregs[0x2912>>1] = gp2x_screenaddr_old[2]; + gp2x_memregs[0x2914>>1] = gp2x_screenaddr_old[3]; + munmap(gp2x_screens[0], 640*480*4); munmap((void *)gp2x_memregs, 0x10000); close(memdev); diff --git a/platform/gp2x/main.c b/platform/gp2x/main.c index 5422b2b6..23d62417 100644 --- a/platform/gp2x/main.c +++ b/platform/gp2x/main.c @@ -12,6 +12,7 @@ #include "gp2x.h" #include "menu.h" #include "emu.h" +#include "940ctl.h" #include "version.h" #include "squidgehack.h" @@ -94,6 +95,7 @@ int main(int argc, char *argv[]) set_RAM_Timings(6, 4, 1, 1, 1, 2, 2); printf("done.\n"); fflush(stdout); } + sharedmem_init(); emu_Init(); engineState = PGS_Menu; @@ -134,6 +136,7 @@ int main(int argc, char *argv[]) endloop: emu_Deinit(); + sharedmem_deinit(); cpuctrl_deinit(); gp2x_deinit(); if(mmuhack_status) -- 2.39.5