Author |
Message |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
|
Back to top
|
|
 |
Inventor
Stream Operator

Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Fri Apr 17, 2009 5:44 am Post subject:
|
 |
|
sounds pretty dang kewl to me. keep us posted on your progress, please... _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
 |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
Posted: Fri Apr 17, 2009 1:20 pm Post subject:
|
 |
|
Next step is to work out a way of increasing the BPM of a drum track.
The plan is to manually determine the points in a file where the drum hits are and then increase the BPM by maintaining the ratios between each of the drum hits. So the track still sounds like the original but faster. This can then be saved as a new WAV files and then beatsliced as before. (Might combine both of these two stages in one not sure at the moment). |
|
Back to top
|
|
 |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
Posted: Thu Apr 23, 2009 2:28 pm Post subject:
|
 |
|
Step 1 completed. Though I have a question which I will come onto later.
Attached is version which allows you to play spinit.wav at a variety of different BPM's. Just adjust the value of bpm_new on line 19. (Going slower than the original BPM gives you get a reverb effect, try 150BPM for example).
Lines 26 to 40 give the points in the drum loop that I wanted alwys to play. The time between these sections is then altered based upon the ratio of bpm to bpm_new.
Code: | // DrumAliens Paul
// ============================
// WAV File Information
// ============================
SndBuf buff => dac;
"F:/My Documents/My Music/Drum Loops/spinit.wav" => buff.read;
2 => int num_bar;
4 => int num_beats;
60.0*num_bar*num_beats*buff.freq() => float bpm;
// ============================
// WAV slice Information
// ============================
// Define the new BPM
250 => float bpm_new;
//bpm => float bpm_new;
15 => int num;
int beat_slice[num];
float beat_time[num];
0 => beat_slice[0];
3455 => beat_slice[1];
5044 => beat_slice[2];
6611 => beat_slice[3];
9792 => beat_slice[4];
11459 => beat_slice[5];
12950 => beat_slice[6];
14715 => beat_slice[7];
16229 => beat_slice[8];
17801 => beat_slice[9];
19027 => beat_slice[10];
20984 => beat_slice[11];
22201 => beat_slice[12];
24384 => beat_slice[13];
25905 => beat_slice[14];
// Determine the time for a single sample
bpm/(bpm_new*buff.freq()*buff.samples()) => float inc_t;
//<<< inc_t >>>;
// Calculate the time in between slices
0.0 => float time_sum;
for (1=>int i; i < beat_slice.cap(); i++){
(beat_slice[i] - beat_slice[i-1])*inc_t => beat_time[i];
beat_time[i] +=> time_sum;
}
// Check the new bpm
<<< bpm, 60.0*num_bar*num_beats/time_sum >>>;
// Starting point for playing the WAV file
0 => int count;
while(1) {
// Work out the position in the WAV file
beat_slice[count] => buff.pos;
//Advance time to the next slice
beat_time[count+1]::second => now;
// Counter
if (count >= beat_time.cap()-2){
0 => count;}
else {
1 +=> count;
}
// <<<count >>>;
}
|
The only problem is that you can end up with clicks as the new sections are spliced together, because they might not start at zero. Is there anyway that I can dynamically change the gain so that at the start of each new section you ramp up the gain rapidly to eliminate this effect ????
Thanks for any help |
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
|
Back to top
|
|
 |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
Posted: Fri Apr 24, 2009 2:10 pm Post subject:
|
 |
|
Kassen, thanks for that. This is going to keep me quiet for a while, whilst I pick my way through what's going on.
Just one question have you a link to the paper you mention.
Thanks |
|
Back to top
|
|
 |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
Posted: Mon Apr 27, 2009 1:16 pm Post subject:
|
 |
|
Resolved my problem with the clicks by putting on a filter on the beginning and the end of any sections of WAV file that are played by attacking the Gain of SndBuf. The filter has a settling time of approximately 5ms which seems long enough to resolve the issue without destroying the original sound of the loop.
The filter should be able to handle any differences in sample times so hopefully it shouldn't need any further changes.
Hey I'm slowly getting the hang of this
Code: | // DrumAliens Paul
// ============================
// WAV File Information
// ============================
SndBuf buff => dac;
"F:/My Documents/My Music/Drum Loops/spinit.wav" => buff.read;
2 => int num_bar;
4 => int num_beats;
60.0*num_bar*num_beats*buff.freq() => float bpm;
// ============================
// WAV slice Information
// ============================
// Define the new BPM
350 => float bpm_new;
15 => int num;
int beat_slice[num];
float beat_time[num];
// Care points of the WAV file
0 => beat_slice[0];
3455 => beat_slice[1];
5044 => beat_slice[2];
6611 => beat_slice[3];
9792 => beat_slice[4];
11459 => beat_slice[5];
12950 => beat_slice[6];
14715 => beat_slice[7];
16229 => beat_slice[8];
17801 => beat_slice[9];
19027 => beat_slice[10];
20984 => beat_slice[11];
22201 => beat_slice[12];
24384 => beat_slice[13];
25905 => beat_slice[14];
// Calculate the sample rate in seconds
1.0/(buff.freq()*buff.samples()) => float Ts;
// Determine the time for a single sample
bpm/(bpm_new*buff.freq()*buff.samples()) => float inc_t;
// Calculate the time in between slices
0.0 => float time_sum;
for (1=>int i; i < beat_slice.cap(); i++){
(beat_slice[i] - beat_slice[i-1])*inc_t => beat_time[i];
beat_time[i] +=> time_sum;
}
// Check the new bpm
<<< bpm, 60.0*num_bar*num_beats/time_sum >>>;
// Setup the Filter variables
0.0 => float yt => float yt_1;
1.0 => float ut;
// Filter Coefficients - will reach steady state in Tset seconds
0.005 => float Tset;
Math.exp(-6.0*Ts/Tset) => float a1;
1.0-a1 => float b0;
while(1) {
// Advance through the parts of the WAV file
for (0 => int count; count < beat_time.cap()-2; count++) {
// Determine the time at the end this section
now + beat_time[count+1]::second => time later;
later - Tset::second => time decay;
// Work out the position in the WAV file
beat_slice[count] => buff.pos;
// Reset the filter for the next section of the WAV file
0.0 => yt_1;
// Loop round each of the samples
while (now < later){
// Advance time by the WAV sample size
Ts::second => now;
// Calculate the 1st Order filter
a1*yt_1 + b0*ut => yt;
// Determine the direction of the input to the filter
if (now > decay)
0.0 => ut;
else
1.0 => ut;
// Store the previous filter value
yt => yt_1;
// Use the filter output to control the output Gain
yt => buff.gain;
}
}
}
|
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Mon Apr 27, 2009 4:04 pm Post subject:
|
 |
|
DrumAliens wrote: | Kassen, thanks for that. This is going to keep me quiet for a while, whilst I pick my way through what's going on. |
You're welcome!
Quote: |
Just one question have you a link to the paper you mention.
|
There is actually a series of papers;
http://www.informatics.sussex.ac.uk/users/nc81/research.php
Anything by Nick related to beat detection/ breakbeat-cutting/etc is worthwhile. You may also want to grab the "BBCut" library for SC and it's documentation if you're serious.
My implementation here is very simple, the main thing is that I start with analysis in order to preserve as much of the natural rhythmic characteristics of the original as possible while cutting. From there on I just shuffle the bits about while preserving their length. I should return to this as the treatment phase here is really quite simple and non-exciting, even though it does sound good from time to time. _________________ Kassen |
|
Back to top
|
|
 |
DrumAliens

Joined: Jul 10, 2008 Posts: 31 Location: UK
Audio files: 1
|
Posted: Mon Apr 27, 2009 10:42 pm Post subject:
|
 |
|
Kassen, I will look into the papers |
|
Back to top
|
|
 |
|