audio improvement wip

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@33 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-02-08 23:19:53 +00:00
parent f80d67e12b
commit 85f8e92973
11 changed files with 65 additions and 27 deletions

View file

@ -227,6 +227,7 @@ void sound_clear(void)
int sound_render(int offset, int length) int sound_render(int offset, int length)
{ {
int buf32_updated = 0;
int *buf32 = PsndBuffer+offset; int *buf32 = PsndBuffer+offset;
int stereo = (PicoOpt & 8) >> 3; int stereo = (PicoOpt & 8) >> 3;
// emulating CD && PCM option enabled && PCM chip on && have enabled channels // 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 // Add in the stereo FM buffer
if (PicoOpt & 1) 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 // CD: PCM sound
if (do_pcm) if (do_pcm) {
pcm_update(buf32, length, stereo); pcm_update(buf32, length, stereo);
//buf32_updated = 1;
}
// CD: CDDA audio // CD: CDDA audio
if ((PicoMCD & 1) && (PicoOpt & 0x800)) if ((PicoMCD & 1) && (PicoOpt & 0x800))

View file

@ -841,7 +841,7 @@ typedef struct
UINT32 eg_timer; UINT32 eg_timer;
UINT32 eg_timer_add; 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 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; INT32 op1_out;
} chan_rend_context; } chan_rend_context;
@ -1077,6 +1077,7 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
} else { } else {
buffer[scounter] += smp; buffer[scounter] += smp;
} }
ct->algo = 8; // algo is only used in asm, here only bit3 is used
} }
/* update phase counters AFTER output calculations */ /* update phase counters AFTER output calculations */
@ -1091,7 +1092,7 @@ void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length)
#endif #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; 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[SLOT3].phase = ct.phase3;
CH->SLOT[SLOT4].phase = ct.phase4; CH->SLOT[SLOT4].phase = ct.phase4;
CH->mem_value = ct.mem; CH->mem_value = ct.mem;
return (ct.algo & 8) >> 3; // had output
} }
/* update phase increment and envelope generator */ /* 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 YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
{ {
int pan; 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, it means it has valid samples to mix with, else it may contain trash
if (is_buf_empty) memset32(buffer, 0, length<<stereo); if (is_buf_empty) memset32(buffer, 0, length<<stereo);
@ -1613,14 +1617,15 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
if (stereo) stereo = 1; if (stereo) stereo = 1;
/* mix to 32bit dest */ /* mix to 32bit dest */
chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)); // flags: stereo, lastchan, disabled, ?, pan_r, pan_l // flags: stereo, lastchan, disabled, ?, pan_r, pan_l
chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)); active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;
chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )); active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;
chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)); active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030) )) << 2;
chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)); active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;
chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2); 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 1; // buffer updated return active_chs; // 1 if buffer updated
} }

View file

@ -162,7 +162,7 @@ void *YM2612GetRegs(void);
#define YM2612PicoStateLoad YM2612PicoStateLoad_ #define YM2612PicoStateLoad YM2612PicoStateLoad_
#else #else
/* GP2X specific */ /* GP2X specific */
#include "../../platform/gp2x/940ctl_ym2612.h" #include "../../platform/gp2x/940ctl.h"
extern int PicoOpt; extern int PicoOpt;
#define YM2612Init(baseclock,rate) { \ #define YM2612Init(baseclock,rate) { \
if (PicoOpt&0x200) YM2612Init_940(baseclock, rate); \ if (PicoOpt&0x200) YM2612Init_940(baseclock, rate); \
@ -172,10 +172,9 @@ extern int PicoOpt;
if (PicoOpt&0x200) YM2612ResetChip_940(); \ if (PicoOpt&0x200) YM2612ResetChip_940(); \
else YM2612ResetChip_(); \ else YM2612ResetChip_(); \
} }
#define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) { \ #define YM2612UpdateOne(buffer,length,stereo,is_buf_empty) \
if (PicoOpt&0x200) YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty); \ (PicoOpt&0x200) ? YM2612UpdateOne_940(buffer, length, stereo, is_buf_empty) : \
else YM2612UpdateOne_(buffer, length, stereo, is_buf_empty); \ YM2612UpdateOne_(buffer, length, stereo, is_buf_empty);
}
#define YM2612Write(a,v) \ #define YM2612Write(a,v) \
(PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v) (PicoOpt&0x200) ? YM2612Write_940(a, v) : YM2612Write_(a, v)
#define YM2612Read() \ #define YM2612Read() \

View file

@ -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. @ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble.
@ - notaz, 2006 @ - notaz, 2006
@ vim:filetype=armasm
.equiv SLOT1, 0 .equiv SLOT1, 0
.equiv SLOT2, 2 .equiv SLOT2, 2
.equiv SLOT3, 1 .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]) @ 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 @ 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 .global chan_render_loop @ chan_rend_context *ct, int *buffer, int length
@ -856,6 +858,7 @@ crl_algo_done:
@ -- WRITE SAMPLE -- @ -- WRITE SAMPLE --
tst r0, r0 tst r0, r0
beq ctl_sample_skip beq ctl_sample_skip
orr r4, r4, #8 @ have_output
tst r12, #1 tst r12, #1
beq ctl_sample_mono beq ctl_sample_mono
@ -908,6 +911,7 @@ crl_do_phase:
crl_loop_end: crl_loop_end:
str r8, [lr, #0x44] @ eg_timer str r8, [lr, #0x44] @ eg_timer
str r12, [lr, #0x4c] @ pack (for lfo_ampm) str r12, [lr, #0x4c] @ pack (for lfo_ampm)
str r4, [lr, #0x50] @ was_update
str r10, [lr, #0x54] @ op1_out str r10, [lr, #0x54] @ op1_out
ldmfd sp!, {r4-r11,pc} ldmfd sp!, {r4-r11,pc}

View file

@ -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; extern char **g_argv;
/* none of the functions in this file should be called before this one */ /* 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 YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty)
{ {
int *ym_buf = shared_data->ym_buffer; int *ym_buf = shared_data->ym_buffer;
int ym_active_chs;
//printf("YM2612UpdateOne_940()\n"); //printf("YM2612UpdateOne_940()\n");
if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE); if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE);
// mix in ym buffer ym_active_chs = shared_ctl->ym_active_chs;
if (is_buf_empty) memcpy32(buffer, ym_buf, length<<stereo);
// else TODO
// for (len = length << stereo; len > 0; len--) // 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<<stereo);
// *dest_buf++ += *ym_buf++; else memset32(buffer, 0, length<<stereo);
// }
if (shared_ctl->writebuffsel == 1) { if (shared_ctl->writebuffsel == 1) {
shared_ctl->writebuff0[writebuff_ptr] = 0xffff; 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); add_job_940(JOB940_YM2612UPDATEONE);
return 1; return ym_active_chs;
} }

View file

@ -1,4 +1,5 @@
void sharedmem_init(void); void sharedmem_init(void);
void sharedmem_deinit(void);
void YM2612Init_940(int baseclock, int rate); void YM2612Init_940(int baseclock, int rate);
void YM2612ResetChip_940(void); void YM2612ResetChip_940(void);

View file

@ -34,7 +34,7 @@ OBJCOPY = $(CROSS)objcopy
# frontend # frontend
OBJS += main.o menu.o gp2x.o usbjoy.o emu.o squidgehack.o asmutils.o cpuctrl.o OBJS += main.o menu.o gp2x.o usbjoy.o emu.o squidgehack.o asmutils.o cpuctrl.o
# 940 core control # 940 core control
OBJS += 940ctl_ym2612.o OBJS += 940ctl.o
# Pico # Pico
OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Utils.o ../../Pico/Memory.o ../../Pico/Misc.o \ 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 ../../Pico/Pico.o ../../Pico/Sek.o ../../Pico/VideoPort.o ../../Pico/Draw2.o ../../Pico/Draw.o

View file

@ -112,7 +112,8 @@ void Main940(void)
YM2612Write_(d >> 8, d); 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; break;
} }

View file

@ -35,6 +35,7 @@ typedef struct
int writebuffsel; /* which write buffer to use (from 940 side) */ int writebuffsel; /* which write buffer to use (from 940 side) */
UINT16 writebuff0[2048]; /* list of writes to ym2612, 1024 for savestates, 1024 extra */ UINT16 writebuff0[2048]; /* list of writes to ym2612, 1024 for savestates, 1024 extra */
UINT16 writebuff1[2048]; UINT16 writebuff1[2048];
int ym_active_chs;
int mp3_len; /* data len of loaded mp3 */ int mp3_len; /* data len of loaded mp3 */
int mp3_offs; /* current playback offset (just after last decoded frame) */ int mp3_offs; /* current playback offset (just after last decoded frame) */
int mp3_buffsel; /* which output buffer to decode to */ int mp3_buffsel; /* which output buffer to decode to */

View file

@ -52,6 +52,7 @@ void *gp2x_screen;
#define FRAMEBUFF_ADDR3 0x4000000-640*480*4 #define FRAMEBUFF_ADDR3 0x4000000-640*480*4
static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 }; static const int gp2x_screenaddrs[] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };
static unsigned short gp2x_screenaddr_old[4];
/* video stuff */ /* video stuff */
@ -269,6 +270,11 @@ void gp2x_init(void)
gp2x_screen = gp2x_screens[0]; gp2x_screen = gp2x_screens[0];
screensel = 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 // snd
mixerdev = open("/dev/mixer", O_RDWR); mixerdev = open("/dev/mixer", O_RDWR);
if (mixerdev == -1) if (mixerdev == -1)
@ -288,6 +294,11 @@ void gp2x_deinit(void)
Pause940(1); Pause940(1);
gp2x_video_changemode(15); 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(gp2x_screens[0], 640*480*4);
munmap((void *)gp2x_memregs, 0x10000); munmap((void *)gp2x_memregs, 0x10000);
close(memdev); close(memdev);

View file

@ -12,6 +12,7 @@
#include "gp2x.h" #include "gp2x.h"
#include "menu.h" #include "menu.h"
#include "emu.h" #include "emu.h"
#include "940ctl.h"
#include "version.h" #include "version.h"
#include "squidgehack.h" #include "squidgehack.h"
@ -94,6 +95,7 @@ int main(int argc, char *argv[])
set_RAM_Timings(6, 4, 1, 1, 1, 2, 2); set_RAM_Timings(6, 4, 1, 1, 1, 2, 2);
printf("done.\n"); fflush(stdout); printf("done.\n"); fflush(stdout);
} }
sharedmem_init();
emu_Init(); emu_Init();
engineState = PGS_Menu; engineState = PGS_Menu;
@ -134,6 +136,7 @@ int main(int argc, char *argv[])
endloop: endloop:
emu_Deinit(); emu_Deinit();
sharedmem_deinit();
cpuctrl_deinit(); cpuctrl_deinit();
gp2x_deinit(); gp2x_deinit();
if(mmuhack_status) if(mmuhack_status)