0
0

Is there a fast way to control individual samples in a sound file?
I’m planning to simulate a noise in a sound file by altering the amplitude of each individual sample, and these amplitudes take a gaussian distribution of possibility. But the real problem is actually accessing the samples.

My idea uses Sound::readData and Sound::seekData, which I saw somewhere in the forum. The functions would allow me to extract a portion from the sound file, like for example, 3 seconds from the sound. From that, I believe I can extract 1 sample from the sound. And from that, I can apply changes to it.

Afterwards, each proceeding samples would be modified. However, I think this is not too practical since there’s 44100 samples per second for a normal mp3 file. And considering there are millions in one song…modifying a single mp3 file would definitely take forever!

Does anyone have another idea? Any help would be appreciated

  • You must to post comments
0
0

Check out the Pitch Detection example file. It shows how you can create a custom DSP unit and then access the stream of samples via a CALLBACK.

Should be a very simple task.

  • You must to post comments
0
0

Thanks for the hint about the callback, tdc. Although I’m still confused on what to do. I saw this one and feel that it might help.

FMOD_RESULT F_CALLBACK FMOD__FMOD_SOUND_PCMREADCALLBACK(
* ,
FMOD_SOUND * sound,
void * data,
unsigned int datalen
);

According to the documentation, it allows me to write into sound. I am yet to experiment on that. Anyway, my mission is changing the amplitude of each individual sample in a sound file so I have to introduce some kind of effect. The only DSP unit that seems to allow this is the "Normalize" effect. However, it amplifies the WHOLE sound file. Is it possible to make some kind of array of numbers, and then feed it into that dsp effect?

Or, if anyone had a better idea, please do tell! I’m noob in programming.

  • You must to post comments
0
0

Hi perrido,

Is there any reason why this has to be done at run time? Would it be possible to bake this into the file. That would probably be the least CPU intensive method of modifying a sound.

If you want to do it at run time it is quite easy. You can create a custom DSP unit to connect to the playing sound and every sample which FMOD is about to play will be passed to your DSP callback first. To see how this works check out the dsp_custom example.

-Pete

  • You must to post comments
0
0

The dsp_custom example just solved a bulk of my problem. great tip peter. Now all I have to worry about is the sound itself.

Just to be sure. Do check if my next procedure is correct:

Since it the gaussian effect would be applied in run time, I would have to use callbacks on the DSP unit instead of the sound itself. I would use FMOD_DSP_SETPOSITIONCALLBACK(FMOD_DSP_STATE * dsp_state, unsigned int position); The dsp state would provide the change in the sound, while the position(in PCM samples) would dictate the exact sample to change.

the dsp state, which is the custom dsp unit, will give a random value everytime the sound advances exactly one sample, therefore providing a different magnitude of effect to the next sample compared to the previous sample. this then is handled with a loop. but I think this plan is too slow.

Could please someone develop the idea?

  • You must to post comments
0
0

I just found out that I could take out the individual values using GetWaveData. I did a test run but it doesn’t seem to compile. The compiler says that there’s a syntax error before getch(). What’s wrong with the code?

FMOD_SYSTEM *system;
FMOD_CHANNEL *channel;
FMOD_SOUND *sound;
FMOD_RESULT result;
float Array[16384];

result = FMOD_System_Create(&system);
result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0);
result = FMOD_System_SetStreamBufferSize(system, 16384, FMOD_TIMEUNIT_PCM);
result = FMOD_System_CreateStream(system, "wave.mp3", FMOD_SOFTWARE | FMOD_LOOP_NORMAL, 0, &sound);

result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel);

result = FMOD_Channel_GetWaveData(channel, Array, 16384, 0)

getch();
result = FMOD_Sound_Release(sound);
result = FMOD_System_Release(system);
result = FMOD_System_Close(system);

  • You must to post comments
0
0

ok that was the dumbest mistake in the history of programming. I left out the semi-colon after the getwavedata line. anyway, I looked at the pluginviewer example and saw that it alloted space for the placement of the array. Is that necessary? I made this code that will output individual samples.

include<stdio.h>

include<conio.h>

include "c:/fmodex/api/inc/fmod.h"

include "c:/fmodex/api/inc/fmod_errors.h"

define CHUNKOFSAMPLES 16384

int main()
{
FMOD_SYSTEM *system;
FMOD_CHANNEL *channel;
FMOD_SOUND *sound;
FMOD_RESULT result;
unsigned int SoundPosition, TotalLength;
static float Array[CHUNKOFSAMPLES];
float *src;
int count, FirstPosition=0;

printf("Playing…\n");

result = FMOD_System_Create(&system);
result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0);
result = FMOD_System_SetStreamBufferSize(system, CHUNKOFSAMPLES, FMOD_TIMEUNIT_PCM);
result = FMOD_System_CreateStream(system, "wave.mp3", FMOD_SOFTWARE, 0, &sound);
result = FMOD_Sound_GetLength(sound, &TotalLength, FMOD_TIMEUNIT_PCM);
result = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, 0, &channel);

memset(Array, 0, CHUNKOFSAMPLES);
while(FirstPosition <= TotalLength)
{
result = FMOD_Channel_GetWaveData(channel, Array, CHUNKOFSAMPLES, 0);
for(count = 0; count < CHUNKOFSAMPLES; count++)
{
printf("%f\n ",Array[count]);
FirstPosition++;
}
}

getch();
result = FMOD_Sound_Release(sound);
result = FMOD_System_Release(system);
result = FMOD_System_Close(system);

return 0;
}

Is there by chance a way in FMOD to use the collected PCM values and make a sound from it?

  • You must to post comments
0
0

[quote:1zbdazdl]I looked at the pluginviewer example and saw that it alloted space for the placement of the array. Is that necessary?[/quote:1zbdazdl]
Yes, FMOD will copy the data to your array, don’t pass in an uninitialized pointer.

[quote:1zbdazdl]Is there by chance a way in FMOD to use the collected PCM values and make a sound from it?[/quote:1zbdazdl]
Yes, you can create sounds using custom PCM data. Take a look at the user created sound example.

-Pete

  • You must to post comments
0
0

Then I guess I’ll leave the memset there. Thanks peter.

GetWaveData doesn’t actually get all PCM samples after all. The amout of samples it gets depends on the speed of the computer. I could use the "approximated" amount of samples.

But is there a better way to get the real amount of PCM samples? The lock function was mentioned in the documentation but it only provides the waveform. I need the quantitative values of each sample.

  • You must to post comments
0
0

The easiest way to get all the samples of a playing sound is to create a custom DSP unit. You are garunteed every sample of the sound will pass through a DSP unit.

Sound::lock is not appropriate for what you’re trying to do, because that just gives you the raw data from the file.

-Pete

  • You must to post comments
Showing 9 results
Your Answer

Please first to submit.