support mp3 (mono) for soundfx

This commit is contained in:
Ondřej Novák 2025-06-15 14:41:53 +02:00
parent dd23d8c989
commit a4aa67ede9
8 changed files with 128 additions and 76 deletions

View file

@ -265,7 +265,7 @@ static void register_mob_sounds(int hlptr,word *sounds)
z=sounds[i]; z=sounds[i];
if (z) if (z)
{ {
def_handle(hlptr,sound_table[z-1],wav_load,SR_ZVUKY); def_handle(hlptr,sound_table[z-1],soundfx_load,SR_ZVUKY);
} }
hlptr++; hlptr++;
} }

View file

@ -650,7 +650,7 @@ const void *pcx_8bit_decomp(const void *p, int32_t *s, int h);
const void *hi_8bit_correct(const void *p, int32_t *s, int h); const void *hi_8bit_correct(const void *p, int32_t *s, int h);
const void *pcx_8bit_nopal(const void *p, int32_t *s, int h); const void *pcx_8bit_nopal(const void *p, int32_t *s, int h);
const void *set_background(const void *p, int32_t *s, int h); const void *set_background(const void *p, int32_t *s, int h);
const void *wav_load(const void *p, int32_t *s, int h); const void *soundfx_load(const void *p, int32_t *s, int h);
const void *load_mob_legacy_format_direct(const void *p, int32_t *s, int h); const void *load_mob_legacy_format_direct(const void *p, int32_t *s, int h);
const void *load_mob_legacy_format(const void *p, int32_t *s, int h); const void *load_mob_legacy_format(const void *p, int32_t *s, int h);
const void *load_spells_legacy_format(const void *p, int32_t *s, int h); const void *load_spells_legacy_format(const void *p, int32_t *s, int h);

View file

@ -206,7 +206,7 @@ void load_items()
break; break;
case SV_SNDLIST: case SV_SNDLIST:
hs=hl_ptr; hs=hl_ptr;
prepare_graphics(&hl_ptr,(char *)p,size,wav_load,SR_ZVUKY); prepare_graphics(&hl_ptr,(char *)p,size,soundfx_load,SR_ZVUKY);
sound_handle=hs-1; sound_handle=hs-1;
free(p); free(p);
break; break;

View file

@ -362,9 +362,9 @@ void spell_anim(char *name)
void spell_sound(char *name) void spell_sound(char *name)
{ {
int i; int i;
i=find_handle(name,wav_load); i=find_handle(name,soundfx_load);
if (i==-1) i=end_ptr++; if (i==-1) i=end_ptr++;
def_handle(i,name,wav_load,SR_ZVUKY); def_handle(i,name,soundfx_load,SR_ZVUKY);
play_sample_at_channel(i,0,100); play_sample_at_channel(i,0,100);
} }

View file

@ -159,24 +159,24 @@ TDREGISTERS registred[]=
{H_POWERLED,"powerled.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_POWERLED,"powerled.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_POSTAVY_DAT,"postavy.dat",NULL,SR_MAP}, {H_POSTAVY_DAT,"postavy.dat",NULL,SR_MAP},
{H_SOUND_DAT,"sound.dat",NULL,SR_MAP}, {H_SOUND_DAT,"sound.dat",NULL,SR_MAP},
{H_SND_SWHIT1,"swd_hit0.wav",wav_load,SR_ZVUKY}, {H_SND_SWHIT1,"swd_hit0.wav",soundfx_load,SR_ZVUKY},
{H_SND_SWHIT2,"swd_hit1.wav",wav_load,SR_ZVUKY}, {H_SND_SWHIT2,"swd_hit1.wav",soundfx_load,SR_ZVUKY},
{H_SND_SWMISS1,"swd_mis0.wav",wav_load,SR_ZVUKY}, {H_SND_SWMISS1,"swd_mis0.wav",soundfx_load,SR_ZVUKY},
{H_SND_SWMISS2,"swd_mis1.wav",wav_load,SR_ZVUKY}, {H_SND_SWMISS2,"swd_mis1.wav",soundfx_load,SR_ZVUKY},
{H_SND_SIP1,"sip2.wav",wav_load,SR_ZVUKY}, {H_SND_SIP1,"sip2.wav",soundfx_load,SR_ZVUKY},
{H_SND_SIP2,"sip1.wav",wav_load,SR_ZVUKY}, {H_SND_SIP2,"sip1.wav",soundfx_load,SR_ZVUKY},
{H_SND_KNIHA,"kniha.wav",wav_load,SR_ZVUKY}, {H_SND_KNIHA,"kniha.wav",soundfx_load,SR_ZVUKY},
{H_SND_OBCHOD,"obchod.wav",wav_load,SR_ZVUKY}, {H_SND_OBCHOD,"obchod.wav",soundfx_load,SR_ZVUKY},
{H_SND_LEKTVAR,"lektvar.wav",wav_load,SR_ZVUKY}, {H_SND_LEKTVAR,"lektvar.wav",soundfx_load,SR_ZVUKY},
{H_SND_TELEPIN,"telepin.wav",wav_load,SR_ZVUKY}, {H_SND_TELEPIN,"telepin.wav",soundfx_load,SR_ZVUKY},
{H_SND_TELEPOUT,"telepout.wav",wav_load,SR_ZVUKY}, {H_SND_TELEPOUT,"telepout.wav",soundfx_load,SR_ZVUKY},
{H_SND_HEK1M,"jauu1m.wav",wav_load,SR_ZVUKY}, {H_SND_HEK1M,"jauu1m.wav",soundfx_load,SR_ZVUKY},
{H_SND_HEK2M,"jauu2m.wav",wav_load,SR_ZVUKY}, {H_SND_HEK2M,"jauu2m.wav",soundfx_load,SR_ZVUKY},
{H_SND_HEK1F,"jauu1f.wav",wav_load,SR_ZVUKY}, {H_SND_HEK1F,"jauu1f.wav",soundfx_load,SR_ZVUKY},
{H_SND_HEK2F,"jauu2f.wav",wav_load,SR_ZVUKY}, {H_SND_HEK2F,"jauu2f.wav",soundfx_load,SR_ZVUKY},
{H_SND_EAT,"jidlo.wav",wav_load,SR_ZVUKY}, {H_SND_EAT,"jidlo.wav",soundfx_load,SR_ZVUKY},
{H_SND_WEAR,"obleci.wav",wav_load,SR_ZVUKY}, {H_SND_WEAR,"obleci.wav",soundfx_load,SR_ZVUKY},
{H_SND_PUTINV,"put_inv.wav",wav_load,SR_ZVUKY}, {H_SND_PUTINV,"put_inv.wav",soundfx_load,SR_ZVUKY},
{H_RUNEBAR1,"r_ohen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RUNEBAR1,"r_ohen.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_RUNEBAR2,"r_voda.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RUNEBAR2,"r_voda.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_RUNEBAR3,"r_zeme.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RUNEBAR3,"r_zeme.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
@ -206,17 +206,17 @@ TDREGISTERS registred[]=
{H_LODKA5,"lesda26a.pcx",pcx_fade_decomp,SR_GRAFIKA}, {H_LODKA5,"lesda26a.pcx",pcx_fade_decomp,SR_GRAFIKA},
{H_LODKA6,"lesda27a.pcx",pcx_fade_decomp,SR_GRAFIKA}, {H_LODKA6,"lesda27a.pcx",pcx_fade_decomp,SR_GRAFIKA},
{H_LODKA7,"lesda28a.pcx",pcx_fade_decomp,SR_GRAFIKA}, {H_LODKA7,"lesda28a.pcx",pcx_fade_decomp,SR_GRAFIKA},
{H_FLETNA,"fletna.wav",wav_load,SR_ZVUKY}, {H_FLETNA,"fletna.wav",soundfx_load,SR_ZVUKY},
{H_FLETNA_BAR,"stupnice.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_FLETNA_BAR,"stupnice.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_FLETNA_MASK,"stupni_m.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, {H_FLETNA_MASK,"stupni_m.pcx",pcx_8bit_nopal,SR_BGRAFIKA},
{H_SND_SEVER,"sever.wav",wav_load,SR_ZVUKY}, {H_SND_SEVER,"sever.wav",soundfx_load,SR_ZVUKY},
{H_SND_VYCHOD,"vychod.wav",wav_load,SR_ZVUKY}, {H_SND_VYCHOD,"vychod.wav",soundfx_load,SR_ZVUKY},
{H_SND_JIH,"jih.wav",wav_load,SR_ZVUKY}, {H_SND_JIH,"jih.wav",soundfx_load,SR_ZVUKY},
{H_SND_ZAPAD,"zapad.wav",wav_load,SR_ZVUKY}, {H_SND_ZAPAD,"zapad.wav",soundfx_load,SR_ZVUKY},
{H_SND_RAND1,"random1.wav",wav_load,SR_ZVUKY}, {H_SND_RAND1,"random1.wav",soundfx_load,SR_ZVUKY},
{H_SND_RAND2,"random2.wav",wav_load,SR_ZVUKY}, {H_SND_RAND2,"random2.wav",soundfx_load,SR_ZVUKY},
{H_SND_RAND3,"random3.wav",wav_load,SR_ZVUKY}, {H_SND_RAND3,"random3.wav",soundfx_load,SR_ZVUKY},
{H_SND_RAND4,"random4.wav",wav_load,SR_ZVUKY}, {H_SND_RAND4,"random4.wav",soundfx_load,SR_ZVUKY},
{H_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_CHARGENM,"chargenm.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, {H_CHARGENM,"chargenm.pcx",pcx_8bit_nopal,SR_BGRAFIKA},

View file

@ -5,6 +5,7 @@
#include <libs/memman.h> #include <libs/memman.h>
#include <platform/sound.h> #include <platform/sound.h>
#include <libs/wav_mem.h> #include <libs/wav_mem.h>
#include <libs/minimp3.h>
#include <libs/event.h> #include <libs/event.h>
#include "globals.h" #include "globals.h"
#include <math.h> #include <math.h>
@ -227,45 +228,25 @@ int set_channel_volume_from_sector(int channel,
} }
/*int calcul_volume(int chan,int x,int y,int side,int volume) static const void *err_sound_load(const void *p, int32_t *s, int h) {
{ *s = sizeof(struct t_wave)+4+1000;
int lv,rv; void *d = getmem(*s);
int ds,bal,i; struct t_wave *hdr = (struct t_wave *)d;
uint32_t *sz = (uint32_t *)(hdr+1);
uint8_t *data = (uint8_t *)(sz+1);
hdr->freq = 1000;
hdr->chans = 1;
hdr->bps = 1000;
hdr->wav_mode = 1;
*sz = 1000;
for (int i = 0; i < 1000; ++i) {
data[i] = (i & 8)?64:192;
}
return d;
}
if (side==-1) side=viewdir;
side&=3; static const void *wav_load(const void *p, int32_t *s, int h)
ds=calc_volume(&x,&y,side);
if (ds<=0)
{
release_channel(chan);
return -1;
}
for(i=0;i<viewdir;i++)
{
bal=x;
x=y;
y=-bal;
}
y=abs(y);
if (abs(x)>y)
if (x>0) bal=100-y*50/x;else bal=-100-y*50/x;
else bal=50*x/y;
ds=ds*volume/100;
if (bal<0)
{
lv=ds*(100+bal)/100;rv=ds;
}
else
{
rv=ds*(100-bal)/100;lv=ds;
}
lv=(lv*sample_volume)>>8;
rv=(rv*sample_volume)>>8;
set_channel_volume(chan,lv,rv);
return 0;
}
*/
const void *wav_load(const void *p, int32_t *s, int h)
{ {
const char *sr; const char *sr;
char *tg; char *tg;
@ -273,10 +254,12 @@ const void *wav_load(const void *p, int32_t *s, int h)
struct t_wave x[3]; struct t_wave x[3];
sr=p; sr=p;
sr=find_chunk(sr,WAV_FMT); sr=find_chunk(sr,WAV_FMT, sr + *s);
if (sr == NULL) return err_sound_load(p, s, h);
read_chunk(sr,&x); read_chunk(sr,&x);
sr=p; sr=p;
sr=find_chunk(sr,WAV_DATA); sr=find_chunk(sr,WAV_DATA, sr+*s);
if (sr == NULL) return err_sound_load(p, s, h);
*s=get_chunk_size(sr); *s=get_chunk_size(sr);
tgr=tg=getmem(*s+sizeof(struct t_wave)+4); tgr=tg=getmem(*s+sizeof(struct t_wave)+4);
memcpy(tgr,x,sizeof(struct t_wave)); memcpy(tgr,x,sizeof(struct t_wave));
@ -289,6 +272,75 @@ const void *wav_load(const void *p, int32_t *s, int h)
return tgr; return tgr;
} }
static const void *mp3_load(const void *p, int32_t *s, int h) {
const uint8_t *ptr = (const uint8_t *)p;
size_t count_samples = 0;
size_t sz = *s;
size_t ofs = 0;
mp3dec_t decoder;
mp3d_sample_t pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
mp3dec_frame_info_t frame;
mp3dec_init(&decoder);
while (ofs<sz) {
int samples = mp3dec_decode_frame(&decoder, ptr+ofs, sz - ofs, pcm, &frame);
if (samples == 0) {
++ofs;
} else {
ofs += frame.frame_bytes;
count_samples += samples/frame.channels;
}
}
if (count_samples == 0) return err_sound_load(p, s, h);
*s = count_samples * 2 + sizeof(struct t_wave)+4;
void *trg = getmem(*s);
struct t_wave *hdr = (struct t_wave *)trg;
hdr->bps = frame.hz * 2;
hdr->chans = 1;
hdr->freq = frame.hz;
hdr->wav_mode = 1;
uint32_t *len = (uint32_t *)(hdr+1);
*len = count_samples * 2;
uint16_t *data = (uint16_t *)(len+1);
mp3dec_init(&decoder);
ofs = 0;
int wrofs = 0;
while (ofs < sz) {
int samples = mp3dec_decode_frame(&decoder, ptr+ofs, sz - ofs, pcm, &frame);
if (samples == 0) {
++ofs;
} else {
ofs += frame.frame_bytes;
for (int i = 0; i < samples; i+=frame.channels) {
if (frame.channels == 1) {
data[wrofs] = pcm[i];
} else if (frame.channels> 1) { //only mono are supported, downgrade
data[wrofs] = (pcm[i] + pcm[i+1]) / 2;
}
++wrofs;
}
}
}
return trg;
}
const void *soundfx_load(const void *p, int32_t *s, int h) {
if (*s >= 12) {
const char *hdr =(const char *)p;
if (hdr[0] == 'R' && hdr[1] == 'I' && hdr[2] == 'F' && hdr[3] == 'F') {
return wav_load(p,s,h);
}
if ((hdr[0] == 'I' && hdr[1] == 'D' && hdr[2] == '3')
|| (hdr[0]==0xFF && (hdr[1] & 0xE0))) {
return mp3_load(p,s,h);
}
}
return err_sound_load(p, s, h);;
}
void play_effekt(int x,int y,int xd,int yd,int sector,int side,const TMA_SOUND *p) void play_effekt(int x,int y,int xd,int yd,int sector,int side,const TMA_SOUND *p)
{ {
int chan; int chan;

View file

@ -3,19 +3,19 @@
#include <stdio.h> #include <stdio.h>
#include "wav_mem.h" #include "wav_mem.h"
const char *find_chunk(const char *wav,char *name) //TODO improve const char *find_chunk(const char *wav,char *name, const char *wav_end) //TODO improve
{ {
int32_t next; int32_t next;
wav+=12; wav+=12;
do while (wav < wav_end)
{ {
if (!strncmp(name,wav,4)) return wav+4; if (!strncmp(name,wav,4)) return wav+4;
wav+=4; wav+=4;
memcpy(&next,wav,4); memcpy(&next,wav,4);
wav+=next+4; wav+=next+4;
} }
while (1); return NULL;
} }
int get_chunk_size(const char *wav) int get_chunk_size(const char *wav)

View file

@ -15,7 +15,7 @@ typedef struct t_wave
int32_t freq,bps; int32_t freq,bps;
}T_WAVE; }T_WAVE;
const char *find_chunk(const char *wav,char *name); const char *find_chunk(const char *wav,char *name, const char *wav_end);
int get_chunk_size(const char *wav); int get_chunk_size(const char *wav);
int read_chunk(const char *wav,void *mem); int read_chunk(const char *wav,void *mem);