![]() |
| Forums | Gaming News | Videos | Downloads | Today's Posts | Mark Forums Read | Chat | FAQ | Members List | Contact |
| ||||||
This is a discussion on A small hack to enable libmikmod to play 2-channel PCM files within the PSP Development Forum forums, part of the PSP Development, Hacks, and Homebrew category; libmikmod (or mikmodlib) is pretty good but it only supports mono PCM (Wav) files at the moment. You'll get a ...
![]() |
|
|
LinkBack | Thread Tools |
|
|
#1 |
![]() |
libmikmod (or mikmodlib) is pretty good but it only supports mono PCM (Wav) files at the moment. You'll get a NULL pointer if trying to load a Wav file with 2 channels. Here is a small hack to make it load and play 2-channel Wav files. Technically speaking, this is not REAL stereo because, libmikmod somehow mixes the 2 channels together. But still, it's better than just having the sound effect played in your left ear only
![]() All we need to do is just to modify few lines in mwav.c as shown below (marked with @_@): Code:
SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
{
SAMPLE *si=NULL;
WAV wh;
BOOL have_fmt=0;
/* read wav header */
_mm_read_string(wh.rID,4,reader);
wh.rLen = _mm_read_I_ULONG(reader);
_mm_read_string(wh.wID,4,reader);
/* check for correct header */
if(_mm_eof(reader)|| memcmp(wh.rID,"RIFF",4) || memcmp(wh.wID,"WAVE",4)) {
_mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
return NULL;
}
/* scan all RIFF blocks until we find the sample data */
for(;;) {
CHAR dID[4];
ULONG len,start;
_mm_read_string(dID,4,reader);
len = _mm_read_I_ULONG(reader);
/* truncated file ? */
if (_mm_eof(reader)) {
_mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
return NULL;
}
start = _mm_ftell(reader);
/* sample format block
should be present only once and before a data block */
if(!memcmp(dID,"fmt ",4)) {
wh.wFormatTag = _mm_read_I_UWORD(reader);
wh.nChannels = _mm_read_I_UWORD(reader);
wh.nSamplesPerSec = _mm_read_I_ULONG(reader);
wh.nAvgBytesPerSec = _mm_read_I_ULONG(reader);
wh.nBlockAlign = _mm_read_I_UWORD(reader);
wh.nFormatSpecific = _mm_read_I_UWORD(reader);
#ifdef MIKMOD_DEBUG
fprintf(stderr,"\rwavloader : wFormatTag=%04x blockalign=%04x nFormatSpc=%04x\n",
wh.wFormatTag,wh.nBlockAlign,wh.nFormatSpecific);
#endif
if((have_fmt)||(wh.nChannels>2)) { // @_@: changed 1 to 2
_mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
return NULL;
}
have_fmt=1;
} else
/* sample data block
should be present only once and after a format block */
if(!memcmp(dID,"data",4)) {
int samp_size, num_samp; // @_@: newly added variables
if(!have_fmt) {
_mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
return NULL;
}
if(!(si=(SAMPLE*)_mm_malloc(sizeof(SAMPLE)))) return NULL;
si->speed = wh.nSamplesPerSec*wh.nChannels; // @_@: changed from (/) to (*)
si->volume = 64;
si->length = len;
samp_size = 1;
if((wh.nBlockAlign/wh.nChannels) == 2) { // @_@: take into account the channel as well
si->flags = SF_16BITS | SF_SIGNED;
//si->length >>= 1; // @_@: keep the size
samp_size = 2; // @_@: 16 bit sample
}
if (wh.nChannels == 2) // @_@: stereo
si->flags |= SF_STEREO;
num_samp = si->length/samp_size/wh.nChannels; // @_@: setting up proper values for si
si->loopstart=0;
si->length=num_samp;
si->loopend=num_samp;
si->panning = PAN_CENTER; // @_@: this one is the most important one!
// was not initialized in the original code so
// it default to PAN_LEFT
si->inflags = si->flags;
SL_RegisterSample(si,MD_SNDFX,reader);
SL_LoadSamples();
/* skip any other remaining blocks - so in case of repeated sample
fragments, we'll return the first anyway instead of an error */
break;
}
/* onto next block */
_mm_fseek(reader,start+len,SEEK_SET);
if (_mm_eof(reader))
break;
}
return si;
}
I believe you can do the same hack to mikmodlib as well. Cheers!
__________________
[url="http://jge.khors.com/"]JGE++ forums[/url] Last edited by dr_watson; 09-28-2006 at 07:44 PM.. |
|
|
|
|
|
#3 |
![]() ![]() Bush Programmer
|
How is that any different that using the pan variable to play a mono file
through both speakers? Code:
int pan = 127; voice = Sample_Play(sf,0,0); Voice_SetVolume(voice, vol); Voice_SetPanning(voice, pan); Personally, what I find interesting is it appears you loaded the sample from memory rather than from a file, care to share? Last edited by Art; 09-28-2006 at 08:15 PM.. Reason: Automerged Doublepost |
|
|
|
|
|
#4 | |
![]() |
Quote:
__________________
[qj now fails.] |
|
|
|
|
|
|
#5 |
![]() ![]() Bush Programmer
|
That's right, but it seems a long way round to reencoding the wav file as mono
for use in a PSP program, unless for some reason you are being forced to read stereo files. ... I'm not trying to be an ahole, I just wonder why that approach... |
|
|
|
|
|
#6 |
![]() |
I'd just like to load the proper "stereo" wav files since I'm using the same wav files for both PSP and PC version of the same game. On the PC side I'm using fmod and of course it plays the wav files in real stereo.
Sure it'll be much better if someone can actually do a proper hack to enable libmikmod to play real stereo noises
__________________
[url="http://jge.khors.com/"]JGE++ forums[/url] |
|
|
|
![]() |
| Tags |
| 2channel , enable , files , hack , libmikmod , pcm , play , small |
| Thread Tools | |
|
|