0
0

Hi, I’m using fmod 3.61 on windows and linux. It’s used to stream mp3, ogg and wav files and it works great. Now I was wondering if it’s possible to have fmod handle other file formats, like for example .flac or any other future audio format. I’ve been looking into FSOUND_File_SetCallbacks and FSOUND_Stream_Create and have understood one can supply it’s own actions upon opening, seeking, reading, closing and streaming a file. This is great, but does it allow one to make fmod handle custom file formats? FSOUND_Stream_OpenFile for example, will fail, if the opened file is not already supported by fmod, so the data should already have been decoded in a supported format during the read callback, I guess… I’m not sure it’s even possible to go this way, but even if it was, it doesn’t look like nice programming practice. Does anyone have any other suggestions, or comments on how to support additional file formats?

chilli

  • You must to post comments
0
0

You may do a thing that won’t deal with fmod, just using dsp units, but you have to decode the stream manually in your source code. decoded samples will then feed fmod buffer through a dsp unit. That’s hard, but this way you have maximum control over your stream format.

  • You must to post comments
0
0

After specifying my own stream callback (following the stream2 example), and making it communicate with my own write callback for the FLAC++ decoder, I managed to feed the fmod stream with the decoded data. It was actually quite easy, but I was intimidated at first by the lack of experience in this field and the somewhat vague documentation on the stream callback. Thanks for your recommendations.

  • You must to post comments
0
0

Ehm could you give a example cause i’m trying to implement the winamp input plugins.

I post some code about that at:
[url:1idc6k5m]http://www.fmod.org/forum/viewtopic.php?t=1633[/url:1idc6k5m]

  • You must to post comments
0
0

Here’s the relevant code of my flac stream class (as requested):
[code:3ealwyw1]
vector<FLACInputStream*> gStreams;

int FLACInputStream::fgCount(0);

signed char FLACInputStream::streamcallback(FSOUND_STREAM *stream, void *buff, int len, int param) {
signed short *stereo16bitbuffer = (signed short *)buff;
if (!fDecoder->process_single()) {
return false;
}
for (int count=0; count<len>>2; count++) { // >>2 = 16bit stereo (4 bytes per sample)
if (count < fDecoder->bufferSize() ) {
*stereo16bitbuffer++ = fDecoder->leftBuffer()[count];
*stereo16bitbuffer++ = fDecoder->rightBuffer()[count];
} else {
*stereo16bitbuffer++ = 0;
*stereo16bitbuffer++ = 0;
}
}
return true;
}
signed char FLACInputStream::streamcallbackWrapper(FSOUND_STREAM *stream, void *buff, int len, int param) {
return gStreams[param]->streamcallback(stream, buff, len, param);
}

FLACInputStream::FLACInputStream(const char filename) {
try {
fDecoder = new FLACDecoder(filename);
} catch (FLACDecoder::FileNotFoundException) {
throw StreamException("File not found: " + string(filename));
}
if (fDecoder->init() != FLAC__SEEKABLE_STREAM_DECODER_OK) {
delete fDecoder;
throw StreamException("FLAC Decoder Not OK");
}
if (!fDecoder->process_until_end_of_metadata()) {
delete fDecoder;
throw StreamException("FLAC Decoder could not read meta data");
}
fStream = FSOUND_Stream_Create(streamcallbackWrapper, 4
fDecoder->bufferSize(), FSOUND_NORMAL | FSOUND_16BITS | FSOUND_STEREO, 44100, fgCount);
if (!fStream) {
throw StreamException(FMOD_ErrorString(FSOUND_GetError()));
}
FSOUND_Stream_SetEndCallback(fStream, endcallbackWrapper, fgCount++);
gStreams.push_back(this);
}
[/code:3ealwyw1]

it is actually simple: the FLACInputStream class creates an instance of the FLACDecoder and an FSOUND_Stream with a streamcallback that will make callbacks to the FLACDecoder.

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.