electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Articles  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links  |  Store
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
Live streaming at radio.electro-music.com

  host / artist show at your time
  Faux Pas Quartet and friends Music From Last Thursday
Please visit the chat
 Forum index » DIY Hardware and Software » ChucK programming language
Sample to BPM conversion
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [10 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Wed Mar 05, 2008 2:15 pm    Post subject: Sample to BPM conversion
Subject description: Anybody know how?
Reply with quote  Mark this post and the followings unread

Hey all,

does anybody know the formula for converting samples into beats per minute? For instance, I know that if i have a loop at 120 BPM it has 88200 samples (at 44.1 khz.) Anyone know how to calculate this?

Just for the record, I arrived at this result using the MusicMath 4.0 BPM/sample/ms conversion calculator which can be downloaded free here:

http://www.hitsquad.com/smm/programs/Music_Math/

It's for MAC.
Back to top
View user's profile Send private message
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Wed Mar 05, 2008 7:17 pm    Post subject: Reply with quote  Mark this post and the followings unread

Well to answer my own post, I found that dividing the number of samples by the sample rate gives you the length in seconds. So now it's about converting seconds (or ms) to BPM. Razz
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Thu Mar 06, 2008 4:49 am    Post subject: Reply with quote  Mark this post and the followings unread

wppk wrote:
So now it's about converting seconds (or ms) to BPM. Razz


Well, that's easy as well. If we want to know the BPM we count the beats that fit in one minute, right? Well, we can simply count how many times a sample fits in a minute!
Code:

//setting up
SndBuf buf => dac;
buf.read("my_sample");

//strongly timed simple reasoning
buf.samples()::samp => dur sample_length;
minute / sample_length => float samples_per_minute;

//we can make it convenient as well if we know stuff about the sample
//let's say we know it to be a simple techno loop
8 => float beats_in_my_sample;

//then we can go
<<< "bpm is" , samples_per_minute * beats_in_my_sample >>>;


There you go, From there on you can send the BPM to other shreds using a static value in a public class and have other shreds sync perfectly to your looped sample, kinda like a DJ except without needing to practice. :¬)

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Thu Mar 06, 2008 7:40 pm    Post subject: Reply with quote  Mark this post and the followings unread

Thanks Kassen. You got me rolling again. Must appreciated. I spent my lunch hour creating a Sample class. I was kind of stuck on the sample conversion bit.

Now I've run into another issue,(imagine that) and I'm not sure if I fully understand Classes and how to properly use them.
Basically, I declared a bunch of variables under the Class, and then when I went to use them as arguments later in the code, I got the Undefined variable in line..

I thought they were already defined when I declared them within the class.

isn't that how it's supposed to work?
Back to top
View user's profile Send private message
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Thu Mar 06, 2008 7:41 pm    Post subject: Reply with quote  Mark this post and the followings unread

Code:
class Samplewrecker {

   
//some declarations
int sixpos[16];
int eipos[8];
int qupos[4];

int T;



float notelength;



//midi shit

MidiMsg input1;

MidiIn min;



//store samples

SndBuf buffer[512];





//load a sample from directory and output tempo
fun void loadsample(string path,int beatnum, int index){



    path => buffer[index].read;

    buffer[index].samples()::samp => dur Ti;

    minute/Ti => float spm;

    beatnum => float beats;

    <<<path>>>;

    <<<"BPM is",spm*beats>>>;

}



// signalpath



 fun void connect(UGen x){

    buffer[512] => x;

}


// offset/duration assignments
T / 2   => int half;
T / 4   => int quart;
T / 8   => int eight;
T / 16  => int six;
T / 32  => int t2;
T / 64  => int t4;
T / 128 => int t5;
T / 256 => int t6;
T / 512 => int t7;


//array assignment: put sample offset positions at index, ie quarter note divisions, eighth etc.



0 => qupos[0]; quart => qupos[1]; quart*2 => qupos[2]; quart*3 => qupos[3];


0 => eipos[0]; eight => eipos[1]; eight*2 => eipos[2]; eight*3 => eipos[3];
eight*4 => eipos[4]; eight*5 => eipos[5]; eight*6 => eipos[6]; eight*7 => eipos[7];

0 => sixpos[0]; six => sixpos[1]; six*2 => sixpos[2]; six*3 => sixpos[3];
six*4 => sixpos[4]; six*5 => sixpos[5]; six*6 => sixpos[6]; six*7 => sixpos[7];
six*8 => sixpos[8]; six*9 => sixpos[9]; six*10 =>sixpos[10];six*11 =>sixpos[11];
six*12 => sixpos[12]; six*13 => sixpos[13]; six*14 =>sixpos[14];six*15 =>sixpos[15];

//go for it

fun void straight(int pos[], int speed, float notlen,int smp) {
   
    while (true) {
       
        for(0=>int i;i< pos.cap();i++) {   
       
    //assign on of the sample array's index to buffer.pos   
    pos[i] => buffer[smp].pos;
   
    //play sample for a duration (eight, six, t1 etc..)
    speed::samp => now;

   
    //stop plaback and advance time to shorten note duration if wanted
    0 => buffer[smp].rate;

   
    notlen::samp => now;
}}
}

fun void jumble(int pos[],int speed, float notlen, int smp) {
   
    while (true) {
           
           pos[Std.rand2(0,4)] => buffer[smp].pos;
           speed::samp => now;

           0 => buffer[smp].rate;

           notlen::samp => now;
        }
    }

   

   



   

fun float note_duration (int divisor) {

   

    T / divisor => notelength;

    return notelength;

   

}

   



fun void listindex(int index){



     <<<buffer>>>;

 }

 

fun void allsamps(){



for(0=>int i; i < buffer.cap();i++) {



      <<<buffer>>>;

      300::ms => now;

  }

       

 }           





}   
//Let the games begin!! sort of...

//Declare 2 objects
    Samplewrecker loader;
    Samplewrecker player;
 

//connect to the dac

loader.buffer[0] => dac;


//call loadsample() and return the BPM (Thanks Kassen) and index number in buffer.
loader.loadsample("slowhopper.aif", 4, 0);

// try to spork the function, but it doesn't recognise the variables?:(
//says Undefined Variables, but I thought I had already defined them within the class.
spork ~ player.straight(eipos[8], eight, eight, 0);

//advance time so shred won't quit
while(true) {100::ms => now;}




Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Fri Mar 07, 2008 5:52 pm    Post subject: Reply with quote  Mark this post and the followings unread

I got why you have your error, there's a error beyond that, but let's first look at this, OK?

You write (in line 202 or so)
Code:
spork ~ player.straight(eipos[8], eight, eight, 0);



The problem starts at "eipos[]". The issue is that "eipos" belongs to the "Samplewrecker" class and that class has several instances. You can't just refer to the name of a member of a class, you need to specify which instance of that class you are talking about (even if there is only one and the name is only used once!) so in this case "eipos[8]" would likely become "player.eipos[8]". at that point you might want to consider reffering to "eipos[8]" inside of the function inside of the class.... or perhaps have the function take a int to be used a index to that array.... But before we go there let me illustrate this issue;

Code:
1 => int foo;

class Bar
 {
 2 => int foo;
 
 fun int returnFoo()
  {
  //refers to the "foo" inside of the class!
  //these are different as you will see.
  return foo;
  }
 }

fun int returnFoo()
 {
 //refers to the one outside of the class!
 return foo;
 }

fun int returnAnotherFoo()
 {
 //temporary variable!
 //this one just exists while the function runs.
 3 => int foo;
 
 //refers to the one inside of this function!
 return foo;
 }

Bar bar;

//outside of class
<<<foo>>>;

//through function
<<<returnFoo()>>>;

//inside
<<<bar.foo>>>;

//through function in class
<<<bar.returnFoo()>>>;


//inside of function
<<<returnAnotherFoo()>>>;


This is what we call "name space"; every "space" (classes and functions) can have their own names that only hold within them and can't be reached from outside without pointing at that name space (or class instance), though, if things aren't defined differently within them functions can reach names outside of themselves.

I realise this is a complex example that can be confusing but it's meant to illustrate a method that actually saves confusion (in the long run...).

I hope that helps you take another step, if not we can try a different way of explaining it. It's probably important to understand this if you want to make the most of classes.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Sat Mar 08, 2008 11:54 pm    Post subject: Reply with quote  Mark this post and the followings unread

Ok. I'm clear on the namespace. Well, I at least understand that every time you call an object of a particular class it must be linked to an instance of the class.

spork ~ player.straight(player.eipos[8]..

i assumed that it wasn't necessary because it was an argument for a function of the class.

I did try this and the compiler allowed it but the argument types don't match now.
Back to top
View user's profile Send private message
Frostburn



Joined: Dec 12, 2007
Posts: 255
Location: Finland
Audio files: 9

PostPosted: Sun Mar 09, 2008 1:56 am    Post subject: Reply with quote  Mark this post and the followings unread

wppk wrote:
spork ~ player.straight(player.eipos[8]..

i assumed that it wasn't necessary because it was an argument for a function of the class.

I did try this and the compiler allowed it but the argument types don't match now.

That's because the function expects an array and you're giving it an int inside an array. Try giving it player.eipos as the argument.
player.eipos[8] is the 9th member of the eipos array, in this case it would throw an Out of Bounds exception because eipos only has 8 members.

_________________
To boldly go where no man has bothered to go before.
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Mar 09, 2008 10:34 am    Post subject: Reply with quote  Mark this post and the followings unread

wppk wrote:

i assumed that it wasn't necessary because it was an argument for a function of the class.


Yes, that makes sense, like when you say "heads up" to a friend you don't mean him to lift the head of a third person.... it's still important to explicit about this because ChucK is a great deal dumber then your friends and can't make stuff out from the context.

This is because you may want a function to do something to a member of another class. Say I have a "wppk" object and a cake object... and the wppk eats the cherry that's on the cake.
Code:

Person wppk;

//not a lie, I swear ;¬)
Cake cake;

wppk.eat( cake.cherry );
wppk.lick(wppk.finger);


;¬)
See why we need this?

We also need the separate namespace inside of functions, if we didn't we would be unable to use temporary variables without first checking all of our code to make sure we didn't already use that one. It's far more convenient to always use "int i" for "index" and trust the VM and compiler will take care of the rest.

I recommend making sure you understand the example above and understand why some of the numbers that come out are the same and others are different and why as this will save a lot of headaches in the long run when working with classes.

Quote:
I did try this and the compiler allowed it but the argument types don't match now.


Yeah, that's the next step ( I trust mr.Frost covered this). This is entirely normal with larger chunks of code everybody gets a few errors, you just resolve them one by one and keep at it and eventually it'll work.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
wppk



Joined: Jan 25, 2008
Posts: 31
Location: Los Angeles

PostPosted: Mon Mar 10, 2008 9:57 am    Post subject: Reply with quote  Mark this post and the followings unread

Thanks so much guys. I've actually got it working now. Well..Almost.
But it's making sound! Very Happy Thanks again for your help on this.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [10 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum
e-m mkii

Please support our site. If you click through and buy from
our affiliate partners, we earn a small commission.


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use