0
0

[I posted this yesterday, but it’s not here anymore! Hope I can remember what I posted. Might be because the site was done. I had to re-register as well.]

All,

I would like to concatenate files in FMOD Designer so that when a call is made those files will play in succession. Sope someone can help.

There are several ways that I’ve tried, and none are very successful for a simple way to stick some files together in succession:

  • I used a "cycle" parameter and put the files in proper place in time for them to play. However, this doesn’t work too well as the files have to be overlapping/touching to play. Otherwise the first one will stop after it is finished. There’s probably an easy workaround for this.
  • I’ve used the dynamic music and linked files together — but this seems like a lot of work just for a simple voice phrase
  • I have a callback that will call another file when the first is finished — This is great for a complex situation where there are lots of phrases. But, for simple concatenation, it’s too much work

I would think that there would be an easy way to stick a couple of files together (w/o editing them) in FMOD Designer and be able to create a call to play the concatenated files.

Thanks for any help!
brad

  • You must to post comments
0
0

Hi brad, welcome to the Forums.

Unfortunately there was a harddisk failure over the weekend, I posted a reply to your post which also got nuked. This is unprecendented so don’t let it taint your FMOD experience :)

For your specific use case of concatenating two files we reccomend that you edit them externally in a DAW and make them into a single file. The main reason is doing that inside game at run-time would incur additional overhead, which could be reduced by simply doing it offline. However, there are ways of doing this using designer :

A) Spawning
Create a soundef contain the waveforms you want to concatenate and sound the sound instance properties to "loop and cutoff".

B) Velocity parameter
Set up a velocity parameter to behave like a timeline then sounds along that parameter.

  • You must to post comments
0
0

I had some success using the EventQueue system for dialogue stuff. Here’s the bulk of a simple test app (which uses Juce as the front end but it should be straightforward to get an idea how this code fits together if you follow calls in the constructor and the buttonClicked() callback function). Of course this doesn’t help you in Designer itself…

Each segment is in a separate event in Designer, the app then edits them together at run time. I suspect this is a little less work than using a callback as the EventQueue system just sits there and does its work.

[attachment=0:turbg46w]Screen shot 2011-07-18 at 09.31.35.png[/attachment:turbg46w]

[code:turbg46w]#ifndef MAINCOMPONENT_H

define MAINCOMPONENT_H

// include the FMOD and Juce headers at set up some other bits and pieces

include "headers.h"

class MainComponent : public Component,
public ButtonListener,
public ComboBoxListener,
public Timer
{
private:

// convenient enumerator for the languages
enum Langs
{
    ENGLISH = 1,
    FRENCH = 2
};  

// FMOD objects
EventSystem* eventsystem;
EventQueue* queue;

// Juce objects
TextButton* playButton;
ComboBox* langMenu;

Label* theNextLabel;
ComboBox* platformMenu;
Label* isTheLabel;
ComboBox* hoursMenu;
ComboBox* minutesMenu;
ComboBox* directionMenu;
ComboBox* stationMenu;

public:
MainComponent ()
: eventsystem(0),
queue(0)
{
initFMODEvent();

    playButton = new TextButton("Play");
    addAndMakeVisible(playButton);
    playButton->addButtonListener(this);

    langMenu = new ComboBox();
    addAndMakeVisible(langMenu);
    langMenu->addItem("English", ENGLISH);
    langMenu->addItem("French", FRENCH);
    langMenu->addListener(this);
    langMenu->setSelectedId(1); // this will trigger the first call to comboBoxChanged() to set language and load the langauge bank

    theNextLabel = new Label("theNextLabel", "the next train from platform");
    addAndMakeVisible(theNextLabel);

    buildPlatformMenu();

    isTheLabel = new Label("isTheLabel", "is the");
    addAndMakeVisible(isTheLabel);

    buildHoursMenu();
    buildMinutesMenu();
    buildDirectionMenu();
    buildStationMenu();

    startTimer(15); // call timerCallback() every 15 ms
}

~MainComponent ()
{                   
    stopTimer();
    deleteAllChildren();
    shutdownFMODEvent();
}

void initFMODEvent()
{                               
    ERRCHECK(EventSystem_Create(&eventsystem));     
    ERRCHECK(eventsystem->init(64, FMOD_INIT_NORMAL, 0, FMOD_EVENT_INIT_NORMAL));

    // the rest of the initialisation is done when the language menu 
    // is used to choose the current language
}

void shutdownFMODEvent()
{
    ERRCHECK(eventsystem->release());
}

void buildPlatformMenu()
{
    platformMenu = new ComboBox();
    addAndMakeVisible(platformMenu);

    int itemID = 1;
    platformMenu->addItem("one", itemID++);
    platformMenu->addItem("two", itemID++);
    platformMenu->addItem("three", itemID++);
    platformMenu->addItem("four", itemID++);
    platformMenu->setSelectedId(1);
}

void buildHoursMenu()
{
    hoursMenu = new ComboBox();
    addAndMakeVisible(hoursMenu);

    int itemID = 1;
    hoursMenu->addItem("nine", itemID++);
    hoursMenu->addItem("ten", itemID++);
    hoursMenu->addItem("eleven", itemID++);
    hoursMenu->setSelectedId(1);
}

void buildMinutesMenu()
{
    minutesMenu = new ComboBox();
    addAndMakeVisible(minutesMenu);

    int itemID = 1;
    minutesMenu->addItem("ten", itemID++);
    minutesMenu->addItem("twenty five", itemID++);
    minutesMenu->addItem("forty", itemID++);   
    minutesMenu->setSelectedId(1);
}

void buildDirectionMenu()
{
    directionMenu = new ComboBox();
    addAndMakeVisible(directionMenu);

    int itemID = 1;
    directionMenu->addItem("service to", itemID++);
    directionMenu->addItem("service arriving from", itemID++);
    directionMenu->setSelectedId(1);
}

void buildStationMenu()
{
    stationMenu = new ComboBox();
    addAndMakeVisible(stationMenu);

    int itemID = 1;
    stationMenu->addItem("durham", itemID++);
    stationMenu->addItem("birmingham", itemID++);
    stationMenu->addItem("london paddington", itemID++);
    stationMenu->setSelectedId(1);
}

void resized ()
{
    langMenu->setBounds(10, 10, getWidth()-20, 20);

    theNextLabel->setBounds(10, 60, getWidth()-20, 20);
    platformMenu->setBounds(10, 90, getWidth()-20, 20);
    isTheLabel->setBounds(10, 120, getWidth()-20, 20);
    hoursMenu->setBounds(10, 150, getWidth()-20, 20);
    minutesMenu->setBounds(10, 180, getWidth()-20, 20);
    directionMenu->setBounds(10, 210, getWidth()-20, 20);
    stationMenu->setBounds(10, 240, getWidth()-20, 20);

    playButton->setBounds(10, getHeight()-40, getWidth()-20, 30);
}

void buttonClicked(Button* button)
{       
    if(button == playButton)
    {                                   
        EventGroup* group;
        ERRCHECK(eventsystem->getGroup("trainstation/root", true, &group));

        // build the sentence on the queue...
        addEventToQueue(group, "the next train from platform");
        addEventToQueue(group, platformMenu->getText().toCString());         
        addEventToQueue(group, "is the");
        addEventToQueue(group, hoursMenu->getText().toCString());
        addEventToQueue(group, minutesMenu->getText().toCString());
        addEventToQueue(group, directionMenu->getText().toCString());
        addEventToQueue(group, stationMenu->getText().toCString());          
    }   
}

void addEventToQueue(EventGroup *group, const char *name)
{       
    Event* event;
    EventQueueEntry* entry;

    ERRCHECK(group->getEvent(name, FMOD_EVENT_INFOONLY, &event));
    ERRCHECK(eventsystem->createEventQueueEntry(event, &entry));
    ERRCHECK(queue->add(entry));
}

void comboBoxChanged(ComboBox* box)
{       
    if(box == langMenu)
    {
        bool shouldReload = false;
        String resourcesPath;

        if(langMenu->getSelectedId() == ENGLISH)
        {
            resourcesPath = File::getSpecialLocation(File::currentExecutableFile)
                                    .getParentDirectory()
                                    .getChildFile(MEDIAPATH)  // MEDIAPATH is dependent on platform
                                    .getFullPathName() + "/"; // the trailing slash is IMPORTANT!
            shouldReload = true;

        }
        else if(langMenu->getSelectedId() == FRENCH)
        {
            resourcesPath = File::getSpecialLocation(File::currentExecutableFile)
                                    .getParentDirectory()
                                    .getChildFile(MEDIAPATH)  // MEDIAPATH is dependent on platform
                                    .getChildFile("french")   // subdirectories for other langs
                                    .getFullPathName() + "/"; // the trailing slash is IMPORTANT!
            shouldReload = true;
        }

        if(shouldReload)
        {
            if(queue)
            {
                // release the old queue if this is not the first language chosen
                ERRCHECK(queue->release());
                queue = 0;
            }

            ERRCHECK(eventsystem->unload());
            ERRCHECK(eventsystem->createEventQueue(&queue));
            ERRCHECK(eventsystem->setMediaPath(resourcesPath.toCString())); 
            ERRCHECK(eventsystem->load("trainstation.fev", 0, 0)); // this also needs the relevant fsb file(s)
        }
    }
}


void timerCallback()
{       
    ERRCHECK(eventsystem->update()); // need to call this regularly, docs say once per "frame"     
}

};

endif //MAINCOMPONENT_H [/code:turbg46w]

  • You must to post comments
0
0

Thanks for your help!

[quote="peter":377v1r8p]
A) Spawning
Create a soundef contain the waveforms you want to concatenate and sound the sound instance properties to "loop and cutoff".
[/quote:377v1r8p]

I don’t know what you mean. I put two files in the Designer in a layer (and also in separate layers) set their properties to "loop and cutoff" and they both start at the same time and loop infinitely.

[quote="peter":377v1r8p]
B) Velocity parameter
Set up a velocity parameter to behave like a timeline then sounds along that parameter.
[/quote:377v1r8p]

  • You must to post comments
0
0

[quote="martinrobinson":177m3gqi]I had some success using the EventQueue system for dialogue stuff. [/quote:177m3gqi]

I appreciate your help. Never knew anything about the EventQueue. Thanks!

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.