Reusing channels

Hello,

I have very basic questions and below is my music player code.

#include <stdio.h>
#include <conio.h>
#include <fmod.h>
#include <windows.h>

FMOD_SYSTEM *g_system;
FMOD_SOUND  *g_sound = NULL;
FMOD_DSP    *g_DSP;

char* g_musicFiles[] = { "c:\\music1.mp3", "c:\\music2.mp3" };
int g_musicFilesCount = 2;

void init() {
	FMOD_System_Create(&g_system);
	FMOD_System_Init(g_system, 1, FMOD_INIT_NORMAL, NULL);
	FMOD_System_CreateDSPByType(g_system, FMOD_DSP_TYPE_PITCHSHIFT, &g_DSP);
}

void release() {
	if (g_sound)
		FMOD_Sound_Release(g_sound);

	FMOD_DSP_Release(g_DSP);
	FMOD_System_Release(g_system);
}

int main(void) {

	int nKey, nFileID = -1;

	float fVolume = 0.5f, fPitch = 1.f, fStep = .1f;

	FMOD_CHANNEL *channel = NULL;

	init();

	while (1) {
		if (_kbhit()) {
			nKey = _getch();

			switch (nKey) {

			case 'p':
				if (g_sound)
					FMOD_Sound_Release(g_sound);

				nFileID = ++nFileID % g_musicFilesCount;

				FMOD_System_CreateSound(g_system, g_musicFiles[nFileID], FMOD_DEFAULT, NULL, &g_sound);
				FMOD_System_PlaySound(g_system, g_sound, NULL, false, &channel);

				FMOD_Channel_SetVolume(channel, fVolume);
				FMOD_Channel_AddDSP(channel, FMOD_CHANNELCONTROL_DSP_HEAD, g_DSP);

				FMOD_DSP_SetParameterFloat(g_DSP, 0, fPitch);
				break;

			case '0':
				fVolume += fStep;
				if (fVolume > 1.0f)
					fVolume = 1.0f;
				FMOD_Channel_SetVolume(channel, fVolume);
				break;

			case '9':
				fVolume -= fStep;
				if (fVolume < 0.0f)
					fVolume = 0.0f;
				FMOD_Channel_SetVolume(channel, fVolume);
				break;

			case '=': case '+':
				if (2.f <= fPitch)
					break;
				fPitch += fStep;
				FMOD_DSP_SetParameterFloat(g_DSP, 0, fPitch);
				break;

			case '-': case '_':
				if (0.5f >= fPitch)
					break;
				fPitch -= fStep;
				FMOD_DSP_SetParameterFloat(g_DSP, 0, fPitch);
				break;

			case 'q':
				release();
				return 0;
			}
		}

		FMOD_System_Update(g_system);
		printf("\r Pitch : %f | Volume : %f", fPitch, fVolume);

		Sleep(100);
	}

	return 0;
}

The main part I’m wondering is case ‘p’ section.

  1. If I need to release the sound, do I have to call FMOD_Channel_RemoveDSP() before FMOD_Sound_Release() too?

  2. Does FMOD_Sound_Release() cancel when FMOD_System_CreateSound() is called and a sound file is still being loaded?

  3. As you can see, I’m reassigning the old values again. I want to match all the settings over all the music.
    How can I reuse the same old channel so that I don’t have to set those again?
    Or what if I want to replay the same music with the same settings when finished?

  4. Is there something wrong, forgot to do, or any advice as for the code above?

This is not my production code, of course, but I wanted to make sure if I’m missing or misunderstanding something before starting the project.

If I need to release the sound, do I have to call
FMOD_Channel_RemoveDSP() before FMOD_Sound_Release() too?

No, you can if you want, but addDSP will remove it from wherever it was previously so you should be ok.

Does FMOD_Sound_Release() cancel when FMOD_System_CreateSound() is called
and a sound file is still being loaded?

No they are not running side by side, they operate in order that you call it. If you call release first, then createSound will happen second.

As you can see, I’m reassigning the old values again. I want to match all the settings
over all the music. How can I reuse the same old channel so that I
don’t have to set those again? Or what if I want to replay the same
music with the same settings when finished?

playSound resets all Channel values, so you will have to re-set everything.
The DSP has its own properties, so the parameters for that are not affected.

Is there something wrong, forgot to do, or any advice as for the code above?

FMOD_System_PlaySound is not pausing the sound with startpaused=true

This means the addDSP and setVolume will happen slightly after you start playing the sound, which might cause a small burst of noise that you dont want.
It is better to set startpaused=true and then after changing attributes, call FMOD_Channel_SetPaused(channel, false);

1 Like

So, if I understood correctly, it means there’s no way to cancel FMOD_System_CreateSound() for some reason when it’s still loading a big file?

Thanks for other explanations too, especially the last one is really helpful.
Never thought that way! Thanks again!

A big file would still only take a second or so to load, but no, you can’t cancel it.

You can override fmod’s file system, and make the read callback give data back to fmod in small chunks. If you wanted to cancel in the middle of a load your file callback could return FMOD_ERR_FILE_BAD or something and the createSound would bail out half way.

1 Like

Oh, I see. Thanks a lot.