### Author Topic: How can I generate a triangle wave with "BASS_SampleCreate"?  (Read 1086 times)

#### riku

• Posts: 17
##### How can I generate a triangle wave with "BASS_SampleCreate"?
« on: 18 May '19 - 10:09 »
Hello.

I want to generate a triangular wave sample for 1 second with "BASS_SampleCreate".
How should I do it?
I'm calling "bass.dll" directly in C #.
Thank you.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #1 on: 20 May '19 - 12:51 »
The sine wave example in the BASS_SampleCreate documentation could be modified for a triangle wave like this:

Code: [Select]
`HSAMPLE sample = BASS_SampleCreate(256, 2 * 28160, 1, 1, BASS_SAMPLE_LOOP | BASS_SAMPLE_OVER_POS); // create sampleshort data[128]; // data bufferint a;for (a = 0; a < 32; a++) { data[a] = 32767 * a / 32; data[32 + a] = 32767 - data[a]; data[64 + a] = -data[a]; data[96 + a] = -32767 + data[a];}BASS_SampleSetData(sample, data); // set the sample's data`
If you want the sample to be a certain length (instead of looping until stopped), you can repeat/duplicate the waveform until it reaches that length.
« Last Edit: 21 May '19 - 17:29 by Ian @ un4seen »

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #2 on: 20 May '19 - 14:03 »
Hi.

How do I specify frequency (Hz) and beep length (milliseconds)?

Best regards.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #3 on: 21 May '19 - 16:15 »
Here's a version that lets you set the frequency and length:

Code: [Select]
`int period = 64; // wave period in samples (should be multiple of 4)int cycles = seconds * frequency; // sample length in cyclesHSAMPLE sample = BASS_SampleCreate(cycles * period * 2, frequency * period, 1, 1, 0); // create sampleshort *data = new short[cycles * period]; // data bufferint a;// generate a cycleint period4 = period / 4;for (a = 0; a < period4; a++) { data[a] = 32767 * a / period4; data[period4 + a] = 32767 - data[a]; data[2 * period4 + a] = -data[a]; data[3 * period4 + a] = -32767 + data[a];}// repeat the cyclesfor (a = 1; a < cycles; a++) memcpy(data + a * period, data, period * 2);BASS_SampleSetData(sample, data); // set the sample's datadelete[] data;`
« Last Edit: 22 May '19 - 12:08 by Ian @ un4seen »

#### Somepony

• Posts: 7
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #4 on: 22 May '19 - 00:27 »
Isnt there should be
Code: [Select]
`memcpy(data + a * period * 2, data, period * 2)`?

Also, this code doesn't allow set high frequencies, since BASS_SampleCreate function fails with unknown error (-1) if second param freq is more than 200000.
« Last Edit: 22 May '19 - 00:33 by Somepony »

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #5 on: 22 May '19 - 05:47 »

But I have something to ask.

Code: [Select]
`short * data = new float [cycles * period];` does not match the type of the array to be assigned to the type of the array actually created.
Also, with
Code: [Select]
`float * data = new float [cycles * period];` I think that memcpy does not go well, but how about that?

Best regards.
« Last Edit: 22 May '19 - 10:12 by riku »

#### Somepony

• Posts: 7
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #6 on: 22 May '19 - 11:16 »
I think there should be short instead of float

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #7 on: 22 May '19 - 12:15 »
Isnt there should be
Code: [Select]
`memcpy(data + a * period * 2, data, period * 2)`?

No, "data" is a "short" pointer, so the "* 2" is automatic. Another (perhaps clearer) way to write it is this:

Code: [Select]
` memcpy(&data[a * period], data, period * sizeof(*data));`
Also, this code doesn't allow set high frequencies, since BASS_SampleCreate function fails with unknown error (-1) if second param freq is more than 200000.

Are you using DirectSound output? That does indeed have a 200000 Hz sample rate limit. There should be no such limit if you use WASAPI output (so that BASS handles mixing) instead. You can also lower the "period" value to bring the required sample rate down.

Code: [Select]
`short * data = new float [cycles * period];` does not match the type of the array to be assigned to the type of the array actually created.

Oops! That's a typo. That post has been updated now.

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #8 on: 22 May '19 - 15:09 »
Hi.

I am coding in C #. How should I write the following part?

Code: [Select]
` memcpy(data + a * period, data, period * 2);`
Could you give me some advice?

Best regards.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #9 on: 23 May '19 - 15:21 »
I'm not a .Net user myself, so I'm not certain, but I think you could use the Array.Copy method. Perhaps something like this:

Code: [Select]
` Array.Copy(data, 0, data, a * period, period);`

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #10 on: 23 May '19 - 15:59 »

Code: [Select]
` Array.Copy(data, 0, data, a * period, period);`
It worked well with the above code.

But I have one question.
When specifying the frequency and the number of seconds with decimals, int type does not work well, but how should I fix it?
C code is fine, so can you tell me?

Best regards.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #11 on: 24 May '19 - 14:41 »
It should be fine for the "seconds" and "frequency" values to be floating-point. The sample's length will be rounded down to a whole cycle (and rate rounded to a whole Hz), but the difference will be small and unnoticeable. If you like, you can set a sample channel (from BASS_SampleGetChannel) to use a fractional rate via the BASS_ATTRIB_FREQ attribute:

Code: [Select]
`BASS_ChannelSetAttribute(channel, BASS_ATTRIB_FREQ, frequency * period);`

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #12 on: 24 May '19 - 16:05 »

I wrote the following code.

Code: [Select]
`float cycles = seconds * frequency;HSAMPLE sample = BASS_SampleCreate(cycles * period * 2, frequency * period, 1, 1, 0);`
However, the first argument of "BASS_SampleCreate" must be specified as an integer, and a value such as 0.04 can not be specified. What should I do?

In addition, how should I specify the number of elements in the creation part of the following array?
Whether to round up cycles or round off, which is better?

Code: [Select]
`short *data = new short[cycles * period]; // data buffer`
Best regards.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #13 on: 24 May '19 - 16:58 »
"seconds" and "frequency" can be floating-point but "cycles" should be left as an integer.

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #14 on: 25 May '19 - 01:17 »
Hello.

Thank you very much.
I can now get it to work almost as desired.
But there is one problem.
As an example, I have specified 0.04 seconds, but if I do this, "BASS_GetLength" will return seconds slightly shorter than the specified number of seconds like 0.0363636363636364 and 0.0353786622443339.
Is there a way to fix this?

Best regards.

#### Ian @ un4seen

• Posts: 22304
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #15 on: 27 May '19 - 13:23 »
The generated sample data contains a whole number of cycles. Generating an extra fractional cycle may result in a "click" sound at the end. If you would prefer to round the length up (instead of down), you can do this:

Code: [Select]
`int cycles = ceil(seconds * frequency); // sample length in cycles`

#### riku

• Posts: 17
##### Re: How can I generate a triangle wave with "BASS_SampleCreate"?
« Reply #16 on: 28 May '19 - 15:23 »