0
0

Hello,

I tried to create a sinewave sample with the frequency of 1KHz and the length of 2 seconds, and, after reading the chm doc and every post I could find on this forum regarding custom sample creation, I came up with the code below. the problem is that it plays no sound at all.. and I can’t seem to figure out the problem .. one more thing : even if I set SECONDS to 20, the program finishes to run in a second or so. If anyone can help, I’d be very grateful.

thank you.

p.s. all the fmod api samples work for me, so it’s not a hardware issue.

[code:xexnabx4]#define SECONDS 2

FSOUND_Init(44100, 16, 0);

FSOUND_SAMPLE *mysample;

mysample = FSOUND_Sample_Alloc(FSOUND_FREE, 44100*SECONDS, FSOUND_16BITS | FSOUND_MONO | FSOUND_SIGNED, 44100, 255, 128, 255);
if (NULL == mysample)
{
printf ("\n failed to alloc sample !\n");
}

int length = FSOUND_Sample_GetLength(mysample);

printf ("\nsample get length (samples) = %d\n", length);

void *buf1 = NULL;
void *buf2 = NULL;
unsigned int len1=0, len2=0;

if (FALSE == FSOUND_Sample_Lock (mysample, 0, length*SECONDS, &buf1, &buf2, &len1, &len2))
{
printf ("\nfailed to lock\n");
}

printf ("\nlen1 (after lock) = %d\n", len1);
printf ("\nlen2 (after lock) = %d\n", len2);

signed short *buff = (signed short *)buf1;

float speed = 1000.0f / (44100.0f * 6.28f);
float t = 0;

for (int count=0; count < length>>1; count++)
{
buff[count] = (signed short)(sin(t) * 32767.0f);
t += speed;
}

if (FALSE == FSOUND_Sample_Unlock (mysample, buf1, buf2, len1, len2))
{
printf ("\nfailed to unlock\n");
}

FSOUND_PlaySound(FSOUND_FREE, mysample);
FSOUND_Close();[/code:xexnabx4]

  • You must to post comments
0
0

damn ! I can’t belive it ! i solved my problem by adding a getch() after FSOUND_PlaySound() … i suppose it was a threading issue or something :-)

  • You must to post comments
0
0

indeed … that would be a good ideea :) ..too bad there’s no sample callback which would be called at the end of sample .. that would’ve solved my polling problem in a more elegantly manner … anyway, i’ve thought of launching the sound parsing method from another thread and make it an infinite loop .. also tried to use timers, but timers suck :/ the polling interval should’ve been too tight …

anyway, I got the thing up and running. there’s just a slight problem :

as I previously posted in another topic, I’m building a morse trainer using fmod. I’ve switched from streaming to pregeneration of the characters’ samples when changing the speed or the tone of transmision.

all works pretty much ok, excepting the fact that at different speed/tone combinations, the samples seem to have some nasty “clicks” and I figure that might be because of the way I generate my samples, which is this one :

(samples consist of intermitent sinewave/silence periods)

[code:3vm7a0e3]
// get dot’s length
m_DotBufferSize = (int)(44100.0f*GetSpeed());

// create the dot template buffer
if (NULL != m_DotBuffer) delete (m_DotBuffer);
m_DotBuffer = new signed short[m_DotBufferSize];

for (i=0; i<m_DotBufferSize; i++)
m_DotBuffer[i] = (signed short)(32767sin(2PIGetTone()(i/44100.0f)));[/code:3vm7a0e3]

then,

[code:3vm7a0e3]// generate letter A sample .. which consists of a “full” dot and a dash
// having between them a “silent” dot
// a dash is three consecutive “full” dots
// so the letter A will become 10111 (dot, silent dot, dot, dot, dot)
// where 1 means a “full” dot and 0 means a “silent” dot

length = m_DotBufferSize * 5; // 5 is size of sample in dot units
sample = FSOUND_Sample_Alloc(0, length, FSOUND_16BITS | FSOUND_MONO | FSOUND_SIGNED, 44100.0f, 255, 128, 255);

void *buf1 = NULL;
void *buf2 = NULL;
unsigned int len1, len2;
FSOUND_Sample_Lock (sample, 0, (length << 1), &buf1, &buf2, &len1, &len2);

signed short *buff = (signed short *)buf1;
int offset = 0;

// put a full dot
memcpy (buff, &m_DotBuffer[offset], (m_DotBufferSize << 1));
buff += m_DotBufferSize;

// put a silent dot
memset (buff, 0, (m_DotBufferSize << 1));
buff += m_DotBufferSize;

// put three consecutive dots
for (int i=0;i<3;i++)
{
memcpy (buff, &m_DotBuffer[offset], (m_DotBufferSize << 1));
buff += m_DotBufferSize;
}[/code:3vm7a0e3]

again .. at some speed/tone combinations, everything’s ok .. at others, there apear some clicks in samples … I’ve also tried to precalc the dash buffer, too, so sin(i) would be cursive from the begining of the dash till the end of it .. still, didn’t help too much ..

thanks for your help

  • You must to post comments
0
0

me again … using square waves instead of sines proved to work properly. there are no more “clicks” apearing inside the samples. but still, the square waves sound pretty rough compared to the sines… I’d like to use sines :/

too see what I’m talking about, insert the following code into the body of “samples/stream2”

[code:2rhx93le]

define MYPI 3.1415926535897932384626433832795

FSOUND_SAMPLE MakeTestSample (float speed, float tone)
{
// get dot’s length
int m_DotBufferSize = (int)(44100.0f
speed);

// create the dot template buffer 
signed short *m_DotBuffer = NULL;
m_DotBuffer = new signed short[m_DotBufferSize]; 

for (int i=0; i&lt;m_DotBufferSize; i++) 
   m_DotBuffer[i] = (signed short)(32767.0*sin(2*MYPI * tone * (i/44100.0f)));

// start to actually create the test sample (full dot, silent dot, full dot, silent dot)

FSOUND_SAMPLE *sample;

int length = 4 * m_DotBufferSize; // length of sample in samples. 4 is number of dots

sample = FSOUND_Sample_Alloc(0, length, FSOUND_16BITS | FSOUND_MONO | FSOUND_SIGNED, 44100, 255, 128, 255);
if (NULL == sample) return NULL;

void *buf1 = NULL;
void *buf2 = NULL;
unsigned int len1, len2;

if (FALSE == FSOUND_Sample_Lock (sample, 0, (length &lt;&lt; 1), &amp;buf1, &amp;buf2, &amp;len1, &amp;len2)) return NULL;

signed short *buff = (signed short *)buf1;

memcpy (buff, m_DotBuffer, (m_DotBufferSize &lt;&lt; 1));
buff += m_DotBufferSize;

memset (buff, 0, (m_DotBufferSize &lt;&lt; 1));
buff += m_DotBufferSize;

memcpy (buff, m_DotBuffer, (m_DotBufferSize &lt;&lt; 1));
buff += m_DotBufferSize;

memset (buff, 0, (m_DotBufferSize &lt;&lt; 1));
buff += m_DotBufferSize;

if (FALSE == FSOUND_Sample_Unlock (sample, buf1, buf2, len1, len2)) return NULL;
return sample;

}

int main()
{
FSOUND_SAMPLE *test;

if (FSOUND_GetVersion() &lt; FMOD_VERSION) return 1;

FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
FSOUND_SetDriver(0); // first available driver

if (!FSOUND_Init(44100, 16, 0)) return 2;


float tone = 600.0f; // Hz
float speed = 0.050f; // seconds

test = MakeTestSample (speed, tone);
printf (&quot;\nplaying at speed %f and tone of %f Hz.\nno clicks here\nPress any key for second sample\n\n&quot;,  speed, tone);
while (!kbhit())
{
    FSOUND_PlaySound(1, test);
    while (FSOUND_IsPlaying(1)) {};
}
getch ();
FSOUND_Sample_Free (test);

tone = 600.0f; // Hz
speed = 0.032f; // seconds

test = MakeTestSample (speed, tone);
printf (&quot;\nplaying at speed %f and tone of %f Hz.\nnotice the clicks !\nPress any key to exit\n&quot;,  speed, tone);
while (!kbhit())
{
    FSOUND_PlaySound(1, test);
    while (FSOUND_IsPlaying(1)) {};
}
getch ();
FSOUND_Sample_Free (test);

FSOUND_Close();
return 0;

}[/code:2rhx93le]

I’d be grateful for any hints.

Thank you.

  • You must to post comments
0
0

I haven’t read your code yet, but what you have to do is make sure that when you generate a sine wave, that the start and the stop values are at a point where the sine becomes zero.
So not just generate 1024 samples, but add some samples until the sine becomes zero again.

  • You must to post comments
0
0

Great ! That was it ! Thank you very much, Adion !

Just changed the way of calculating the “dot” sample buffer into :

[code:2zqsc56x]// get dot’s real length
int m_DotBufferSize = (int)(44100.0f*speed);

// adjust in order to have the buffer start and end at 0
int iter = 0;
while (((signed short)(32767.0sin(2MYPI * tone * ((m_DotBufferSize – 1 + iter)/44100.0f)))) != 0)
{
iter++;
}
m_DotBufferSize += iter;[/code:2zqsc56x]

Thanks again !

  • You must to post comments
0
0

One more thing I just thought about :
I think that with the method you just wrote, it is possible that it will never be exactly 0 (it might go … 5 2 -1 -5 …), so if you want it really correct, you would have to search for a sign change (when the previous sample and the next one have a different sign)

  • You must to post comments
Showing 6 results
Your Answer

Please first to submit.