0
0

Hi guys,

I have an application that can synch and mix different music samples in real-time. It stitches samples together as well as overlays them. All the synching is done using the dsp clock by setting delays on channels.

I now want to turn this into an application that mixes down the result (without playing it). So the application would produce a list of files that need to be played and at what time:

0ms file1.wav
0ms file2.wav
4000ms file3.wav
5000ms file4.wav
5000ms file1.wav
etc.

Then the FMOD code would use this list to produce a mixdown of the whole thing. I don’t want to play the result, just produce the file offline.

Is such a thing possible in FMOD?

Cheers,

Alan.

  • You must to post comments
0
0

Loading them as samples would be worth a try. It’s also worth resampling the source files if that is feasible for your non-test environment. You could also try using the FSBank tool to encode your source files into a PCM format FSB (same as wav files with some loading omptimisations).

  • You must to post comments
0
0

[quote="peter":3o86v2x9]It might be faster if you use load the sound into memory rather than repeatedly creating and releasing streams. (createSound with FMOD_CREATESAMPLE (default) instead of createStream)
If all you want is for the sound to loop, you could using FMOD_LOOP_NORMAL flag rather than doing all that manual scheduling using setDelay. Apart from that it appears the most expensive thing in your mixer setup would be resampling, so if you convert your music.wav to the same samplerate as what FMOD is running that would speed things up slightly.[/quote:3o86v2x9]

Hi Peter,

Thanks for your reply. Unfortunately I won’t be using the same WAV file. The code I presented is just for testing purposes. Actually it would be playing different WAV files after each other (and sometimes more than one WAV file at the same time). So I am forced to repeatedly create and release streams. Maybe I can load them as samples instead of streams? This is how I’m doing it at the moment:

[code:3o86v2x9]result = FMOD_System_CreateStream(h_audio_sys, "music.wav", FMOD_SOFTWARE, 0, &h_sound_now);[/code:3o86v2x9]

I tried playing around with the buffer size by changing it to values other than 1024 – I tried 2048, 4096 and 8192 – but that didn’t make much of a difference except for when I set it to 8192 in which case the mixdown took considerably longer.

Alan.

  • You must to post comments
0
0

It might be faster if you use load the sound into memory rather than repeatedly creating and releasing streams. (createSound with FMOD_CREATESAMPLE (default) instead of createStream)
If all you want is for the sound to loop, you could using FMOD_LOOP_NORMAL flag rather than doing all that manual scheduling using setDelay. Apart from that it appears the most expensive thing in your mixer setup would be resampling, so if you convert your music.wav to the same samplerate as what FMOD is running that would speed things up slightly.

  • You must to post comments
0
0

Can anyone tell me if mixing down 30 mins of music should take 3 mins? Is this normal or am I doing something wrong? How can we make this faster?

Cheers,

Alan.

  • You must to post comments
0
0

Hi guys,

I’ve managed to make this work. Many thanks for your help. I now have a question regarding the speed of non-realtime mixing – it seems very slow to me. I am looping a 12-second wav file for around 30 mins and mixing down the result – this works fine but it takes over 3 mins to finish (on a very well-specced PC).

Here is my code (C++):

[code:39covve1]
FMOD_SYSTEM* h_audio_sys; //handle to system
FMOD_SOUND* h_sound_now; //handle to sound currently playing
FMOD_SOUND* h_sound_prev(0); //handle to previous sound
FMOD_CHANNEL* h_channel; //handle to channel
unsigned int min_delay; //delay
double min_delay_s; //delay in seconds
FMOD_RESULT result; //code of any error messages
Uint64P start_time; //start time of the recording
double start_time_s; //start time in seconds
Uint64P choice_time; //time when we setup the next arrangement
Uint64P end_time; //end time of current arrangement (and start time of next)
double elapsed_time_s; //elapsed time in seconds
unsigned int sample_rate(44100) //the sample rate
double length_s(30); //length of the mixdown

//initalize the system----------------------------------------------------------------------
// create a System object and initialize
result = FMOD_System_Create(&h_audio_sys);
if (!ResultOK(result, "FMOD_System_Create()")) return false;

//set the output to non-realtime record
result = FMOD_System_SetOutput(h_audio_sys, FMOD_OUTPUTTYPE_WAVWRITER_NRT);
if (!ResultOK(result, "FMOD_System_SetOutput()")) return false;

//set the output sample rate
result = FMOD_System_SetSoftwareFormat(h_audio_sys, sample_rate, FMOD_SOUND_FORMAT_PCM16, 2, 6, FMOD_DSP_RESAMPLER_LINEAR);
if (!ResultOK(result, "FMOD_System_SetSoftwareFormat()")) return false;

//init the system (and specify name of output wav file)
result = FMOD_System_Init(h_audio_sys, 100,  FMOD_INIT_STREAM_FROM_UPDATE, file_name);
if (!ResultOK(result, "init_system.FMOD_System_SetOutput()")) return false;

//set volume
FMOD_CHANNELGROUP* channel_group;
FMOD_System_GetMasterChannelGroup(h_audio_sys, &channel_group);
FMOD_ChannelGroup_SetVolume(channel_group, 1);
//------------------------------------------------------------------------------------------

//load sound -------------------------------------------------------------------------------
result = FMOD_System_CreateStream(h_audio_sys, "music.wav", FMOD_SOFTWARE, 0, &h_sound_now);
if (!ResultOK(result, "FMOD_System_CreateStream()")) return false;
//------------------------------------------------------------------------------------------

//set delay using buffer size --------------------------------------------------------------
result = FMOD_System_GetDSPBufferSize(h_audio_sys, &min_delay, 0);
if (!ResultOK(result, "FMOD_System_GetDSPBufferSize()")) return false;
min_delay *= 2;
min_delay_s = ((double)min_delay) / ((double)sample_rate);
//------------------------------------------------------------------------------------------

//put sound in channel in a paused state ---------------------------------------------------
result = FMOD_System_PlaySound(h_audio_sys, FMOD_CHANNEL_FREE, h_sound_now, true, &h_channel);
if (!ResultOK(result, "FMOD_System_PlaySound()")) return false;
//------------------------------------------------------------------------------------------

//get the start_time of the recording & add small delay to it ------------------------------
result = FMOD_Channel_GetDelay(h_channel,  FMOD_DELAYTYPE_DSPCLOCK_START, &start_time.mHi, &start_time.mLo);
if (!ResultOK(result, "FMOD_Channel_GetDelay()")) return false;
start_time += min_delay;
start_time_s = start_time / sample_rate;
//------------------------------------------------------------------------------------------

//set the start time of the channel and unpause it------------------------------------------
result = FMOD_Channel_SetDelay(h_channel, FMOD_DELAYTYPE_DSPCLOCK_START, start_time.mHi, start_time.mLo);
if (!ResultOK(result, "FMOD_Channel_SetDelay()")) return false;
result = FMOD_Channel_SetPaused(h_channel, false);
if (!ResultOK(result, "FMOD_Channel_SetPaused()")) return false;
//------------------------------------------------------------------------------------------

//calculate when we need to setup the next sample & also when we need to start it -----
end_time = start_time;
end_time += get_arr_length_pcm(sample_rate);
choice_time = end_time;
choice_time -= min_delay;
//------------------------------------------------------------------------------------------

bool finish_up(false);          //true if the sample we are playing should be the last one
bool stop(false);               //true if we need to stop recording

while (!stop)
{
    //get current dsp time -----------------------------------------------------------------
    Uint64P dsp_time;
    result = FMOD_System_GetDSPClock(h_audio_sys, &dsp_time.mHi, &dsp_time.mLo);
    if (!ResultOK(result, "update.FMOD_System_GetDSPClock()")) return false;
    //--------------------------------------------------------------------------------------

    //get current time in seconds ----------------------------------------------------------
    elapsed_time_s = (dsp_time / sample_rate) - start_time_s;
    //--------------------------------------------------------------------------------------

    //setup the next sample if necessary-----------------------------------------------
    if ( !finish_up && ( (dsp_time.mHi >= choice_time.mHi) && (dsp_time.mLo >= choice_time.mLo) ))
    {
        if ( (elapsed_time_s + min_delay_s) >= length_s )  //is this the last sample to be played?
        {
            if (h_sound_prev )
            {
                result = FMOD_Sound_Release(h_sound_prev);
                if (!ResultOK(result, "FMOD_Sound_Release() [1]")) return false;
            }
            finish_up = true;
        }
        else
        {
            //free any previous sounds -----------------------------------------------------------------
            if (h_sound_prev )
            {
                result = FMOD_Sound_Release(h_sound_prev);
                if (!ResultOK(result, "FMOD_Sound_Release() [2]")) return false;
            }
            //------------------------------------------------------------------------------------------

            //store the sound currently playing --------------------------------------------------------
            h_sound_prev = h_sound_now;
            //------------------------------------------------------------------------------------------

             //load sound -------------------------------------------------------------------------------
            result = FMOD_System_CreateStream(h_audio_sys, "music.wav", FMOD_SOFTWARE, 0, &h_sound_now);
            if (!ResultOK(result, "FMOD_System_CreateStream()")) return false;
            //-------------------------------------------------------------------------------------------

            //put sound in channel in a paused state ---------------------------------------------------
            result = FMOD_System_PlaySound(h_audio_sys, FMOD_CHANNEL_FREE, h_sound_now, true, &h_channel);
            if (!ResultOK(result, "FMOD_System_PlaySound()")) return false;
            //------------------------------------------------------------------------------------------

            //set the start time of the channel and unpause it------------------------------------------
            start_time = end_time;
            result = FMOD_Channel_SetDelay(h_channel, FMOD_DELAYTYPE_DSPCLOCK_START, start_time.mHi, start_time.mLo);
            if (!ResultOK(result, "FMOD_Channel_SetDelay()")) return false;
            result = FMOD_Channel_SetPaused(h_channel, false);
            if (!ResultOK(result, "FMOD_Channel_SetPaused()")) return false;
            //------------------------------------------------------------------------------------------

            //calculate when we need to setup the next sample & also when we need to start it -----
            end_time = start_time;
            end_time += get_arr_length_pcm(sample_rate);
            choice_time = end_time;
            choice_time -= min_delay;
            //------------------------------------------------------------------------------------------
        }
    }
    //--------------------------------------------------------------------------------------

    //if the last sample has finished playing than exit--------------------------------
    if ( finish_up && ( (dsp_time.mHi >= end_time.mHi) && (dsp_time.mLo >= end_time.mLo) ))
        stop = true;
    //--------------------------------------------------------------------------------------

    //update the audio system---------------------------------------------------------------
    result = FMOD_System_Update(h_audio_sys);
    if (!ResultOK(result, "FMOD_System_Update()")) return false;
    //--------------------------------------------------------------------------------------
}

//-release sound and audio system ----------------------------------------------------------
FMOD_Sound_Release(h_sound_now);
if (!ResultOK(result, "FMOD_Sound_Release() [3]")) return false;
FMOD_System_Release(h_audio_sys);
//------------------------------------------------------------------------------------------

[/code:39covve1]

Any ideas on how I can make this faster?

Cheers,

Alan.

  • You must to post comments
0
0

System::update will mix a single block, the size of which can be configured using System::setDSPBufferSize, the default on PC is 1024 samples.

Yes wav is the only format supported, FMOD Ex is a playback library not an encoder. We do provide an encoder library calld FSBANK lib, it will encode FMOD SoundBank files (FSB). It supports a variety of compression formats including MP3.

  • You must to post comments
0
0

Set the output type to FMOD_OUTPUTTYPE_WAVWRITER_NRT

[quote:1dqn2qrx]FMOD_OUTPUTTYPE_WAVWRITER_NRT

All – Non-realtime version of FMOD_OUTPUTTYPE_WAVWRITER. User can drive mixer with System::update at whatever rate they want. [/quote:1dqn2qrx]

  • You must to post comments
0
0

[quote="peter":1j8iit1j]User can drive mixer with System::update at whatever rate they want. [/quote:1j8iit1j]

How does that work? By how much do we move forward in time everytime we call system::update? 1 sample?

Also, is WAV the only format I can write to? Are any other formats like MP3 supported?

Cheers,

Alan.

  • You must to post comments
0
0

[quote="audiodev":1zbuvtxb]Check out the wav writer sample.[/quote:1zbuvtxb]

Thanks for your reply. Could you tell me where this is? I couldn’t find it in the examples folder. Also, I’m only interested in offline mixdown where you wouldn’t hear the mixdown and the mixdown happens much faster.

Cheers,

Alan.

  • You must to post comments
0
0

Check out the wav writer sample.

  • You must to post comments
Showing 10 results
Your Answer

Please first to submit.