[PD-cvs] externals/frankenstein themes_memory.c, NONE, 1.1 themes_memory.sln, NONE, 1.1 themes_memory.suo, NONE, 1.1 themes_memory.vcproj, NONE, 1.1
dmorelli
morellid at users.sourceforge.net
Thu Jan 5 00:33:35 CET 2006
- Previous message: [PD-cvs] abstractions/pureunity README, 1.6, 1.7 TODO, 1.2, 1.3 ChangeLog, 1.2, 1.3 main.pd, 1.3, 1.4
- Next message: [PD-cvs] pd/src d_fft.c,1.2.4.1.2.1,1.2.4.1.2.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/externals/frankenstein
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20246
Added Files:
themes_memory.c themes_memory.sln themes_memory.suo
themes_memory.vcproj
Log Message:
checking in the themes_memory skeleton, just a copy of rhythms_memory
--- NEW FILE: themes_memory.sln ---
Microsoft Visual Studio Solution File, Format Version 7.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "themes_memory", "themes_memory.vcproj", "{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}"
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Debug.ActiveCfg = Debug|Win32
{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Debug.Build.0 = Debug|Win32
{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Release.ActiveCfg = Release|Win32
{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
--- NEW FILE: themes_memory.suo ---
(This appears to be a binary file; contents omitted.)
--- NEW FILE: themes_memory.c ---
/*
themes_memory
Authors:
Davide Morelli http://www.davidemorelli.it
David Plans Casal http://www.studios.uea.ac.uk/people/staff/casal
uses graphs to store melodies
it is just like rhythms_memory but works on the more complex world of themes
TODO:
* memory save/load to file (?)
* output rhythms in the form of list of floats (easy)
* add velo (?)
* input rhythms from a list (second inlet) (easy)
* let it create variations on known rhythms (?)
* let it merge rhythms (?)
*/
#include "m_pd.h"
#include "common.h"
#include <time.h>
#include <math.h>
#include <stdlib.h>
static t_class *themes_memory_class;
typedef struct event event;
typedef struct event
{
unsigned short int voice;
double when;
event *next;
};
typedef struct _themes_memory
{
t_object x_obj; // myself
// 3 outlets:
// bangs_out plays the wanted rhythmsin realtime
// list_out outputs the wanted rhythm as a list of floats
// info_out outputs info on the last recognized rhythm
t_outlet *bangs_out, *list_out, *info_out;
t_rhythm_event *curr_seq;
int seq_initialized;
// the memory
t_rhythm_memory_representation *themes_memory;
// measure length
double measure_start_time;
double measure_length;
// input rhythm's events
event *events;
// output rhythm's events
unsigned short int next_main_rhythm_out;
unsigned short int next_sub_rhythm_out;
event *events_out;
t_clock *x_clock;
double x_deltime;
double last_event_out_time;
} t_themes_memory;
void themes_memory_free(t_themes_memory *x)
{
if (x->curr_seq)
freeBeats(x->curr_seq);
if (x->themes_memory)
rhythm_memory_free(x->themes_memory);
clock_free(x->x_clock);
}
// called when a new measure starts
void start_measure(t_themes_memory *x)
{
// I call the pd functions to get a representation
// of this very moment
x->measure_start_time = clock_getlogicaltime();
x->last_event_out_time = 0;
}
// called when a new event occours
void add_event(t_themes_memory *x, unsigned short int voice)
{
event *newEvent, *currEvent, *lastEvent;
double when;
when = clock_gettimesince(x->measure_start_time);
newEvent = (event *) malloc(sizeof(event));
newEvent->when = when;
newEvent->voice = voice;
newEvent->next = 0;
currEvent = x->events;
if (currEvent)
{
// this is not the first event
while(currEvent)
{
lastEvent = currEvent;
currEvent = currEvent->next;
}
lastEvent->next = newEvent;
} else
{
// this is the first event
x->events = newEvent;
}
post("event added");
}
// called when a measure ends
void end_measure(t_themes_memory *x)
{
float fduration;
event *currEvent, *lastEvent;
unsigned short int is_it_a_new_rhythm;
unsigned short int id, subid;
float root_closeness, sub_closeness;
int counter;
t_atom *lista;
// these 2 are for output rhythm
int rhythm_found;
t_rhythm_event *wanted_rhythm;
t_rhythm_event *curr_rhythm;
event *lastOutEvent;
// I call the pd functions to get a representation
// of this very moment
x->measure_length = clock_gettimesince(x->measure_start_time);
// now that i know the exact length of the current measure
// i can process the rhythm in the current measure
// and evaluate it
currEvent = x->events;
// this is not the first event
// now I translate events in rhythm
counter = 0;
while(currEvent)
{
fduration = (float) (((float) currEvent->when) / ((float) x->measure_length));
if (x->seq_initialized)
{
concatenateBeat(x->curr_seq, currEvent->voice, fduration, 1);
} else
{
setFirstBeat(&(x->curr_seq), currEvent->voice, fduration, 1);
x->seq_initialized = 1;
}
currEvent = currEvent->next;
counter++;
}
// delete events after having evaluated them
currEvent = x->events;
// this is not the first event
while(currEvent)
{
lastEvent = currEvent;
currEvent = currEvent->next;
free(lastEvent);
}
x->events = 0;
if (x->curr_seq)
{
// now I evaluate this rhythm with the memory
rhythm_memory_evaluate(x->themes_memory, x->curr_seq, &is_it_a_new_rhythm,
&id, &subid, &root_closeness, &sub_closeness);
// tell out the answer
// allocate space for the list
lista = (t_atom *) malloc(sizeof(t_atom) * 5);
SETFLOAT(lista, (float) is_it_a_new_rhythm);
SETFLOAT(lista+1, (float) id);
SETFLOAT(lista+2, (float) subid);
SETFLOAT(lista+3, (float) root_closeness);
SETFLOAT(lista+4, (float) sub_closeness);
outlet_anything(x->info_out,
gensym("list") ,
5,
lista);
free(lista);
// rhythm_memory_evaluate freed the memory for the rhythm if needed
x->seq_initialized = 0;
x->curr_seq = 0;
}
// I free the list of events_out (if present)
currEvent = x->events_out;
// this is not the first event
while(currEvent)
{
lastEvent = currEvent;
currEvent = currEvent->next;
free(lastEvent);
}
x->events_out = 0;
// i set up the list of events_out
// for the wanted rhythm
if (x->next_main_rhythm_out)
{
wanted_rhythm = 0;
// ask the memory for the wanted rhythm
rhythm_found = rhythm_memory_get_rhythm(x->themes_memory, // the memory
&wanted_rhythm, // a pointer to the returned rhythm
// the id of the main rhythm wanted
x->next_main_rhythm_out,
// the sub-id of the sub-rhythm wanted
x->next_sub_rhythm_out);
if (rhythm_found==0)
{
post("themes_memory: rhythm %i %i was not found ", x->next_main_rhythm_out, x->next_sub_rhythm_out);
return 0;
}
if (wanted_rhythm==0)
{
error("themes_memory: wanted_rhythm should not be null! ");
return 0;
}
// now I setup the events_out list
// for each event in wanted_rhythm
// allocate and link an element of elements_out
curr_rhythm = wanted_rhythm;
lastOutEvent = 0;
while (curr_rhythm)
{
event *newEvent;
newEvent = malloc(sizeof(event));
newEvent->next = 0;
newEvent->voice = curr_rhythm->voice;
newEvent->when = (double) (duration2float(curr_rhythm->start) * x->measure_length);
post("DEBUG: add event in moment: %f", newEvent->when);
if (x->events_out)
{
// this is not the first event
// assign the next
lastOutEvent->next = newEvent;
} else
{
// this is the first event
x->events_out = newEvent;
}
// change the last pointer
lastOutEvent = newEvent;
curr_rhythm = curr_rhythm->next;
}
// also setup the timer for the first event
if (x->events_out)
{
// setup the clock
clock_delay(x->x_clock, x->events_out->when);
// remember when next event will occour
x->last_event_out_time = x->events_out->when;
// remember the curr event
lastOutEvent = x->events_out;
//reassign next event
x->events_out = x->events_out->next;
// free old event
free(lastOutEvent);
}
x->next_main_rhythm_out = 0;
}
// also start the new measure!
start_measure(x);
}
// this function is called by pd
// when the timer bangs
static void rhythms_tick(t_themes_memory *x)
{
event *lastOutEvent;
// here i must:
// take the next element in x->events_out
// and compute when I'll need to schedule next event
// (next_event - curr_event)
// set the next element as the current one
// and free the memory allocated for the old curr event
// set up the timer
post("DEBUG: eveng bang");
// first of all trigger the bang!
outlet_bang(x->bangs_out);
//then do the stuff
if (x->events_out)
{
// setup the clock
clock_delay(x->x_clock, x->events_out->when - x->last_event_out_time);
// remember when next event will occour
x->last_event_out_time = x->events_out->when ;
// remember the curr event
lastOutEvent = x->events_out;
//reassign next event
x->events_out = x->events_out->next;
// free old event
free(lastOutEvent);
}
}
// the user wants me to play a rhythm in the next measure
// the user MUST pass 2 args: main_rhythm and sub_rhythm wanted
static void ask_rhythm(t_themes_memory *x, t_symbol *s, int argc, t_atom *argv)
{
if (argc<2)
{
error("this method needs at least 2 floats: main_rhythm and sub_rhythm wanted");
return;
}
//argv++;
x->next_main_rhythm_out = atom_getfloat(argv++);
x->next_sub_rhythm_out = atom_getfloat(argv);
post("DEBUG: asked rhythm %i %i", x->next_main_rhythm_out, x->next_sub_rhythm_out);
// i have nothing left to do:
// when this measure will end a list of events_out will be set
// from the current values of x->next_main_rhythm_out and x->next_sub_rhythm_out
}
// add this rhythm to the memory
static void add_rhythm(t_themes_memory *x, t_symbol *s, int argc, t_atom *argv)
{
// TODO
post("TODO");
}
// creates a variation of a given rhythm (in memory)
// with a given degree of closeness
static void variation(t_themes_memory *x, t_symbol *s, int argc, t_atom *argv)
{
// TODO
post("TODO");
// get the rhythm
// using the transitions table create a new one
// add it to the memory?
// output to the list outlet?
// set it as the next played rhythm
}
static void themes_memory_bang(t_themes_memory *x) {
// generate a random value
float rnd;
t_rhythm_event *events;
t_duration dur;
rnd = rand()/((double)RAND_MAX + 1);
dur = float2duration(rnd);
post("random value=%f duration.numerator=%i duration.denominator=%i", rnd, dur.numerator, dur.denominator);
if (x->seq_initialized)
{
concatenateBeat(x->curr_seq, 0, rnd, 1);
} else
{
setFirstBeat(&(x->curr_seq), 0, rnd, 1);
x->seq_initialized = 1;
}
// print the sequence
events = x->curr_seq;
while(events)
{
post("event: numerator=%i, denominator=%i", events->duration.numerator, events->duration.denominator);
events=events->next;
}
}
void *themes_memory_new(t_symbol *s, int argc, t_atom *argv)
{
int i;
time_t a;
t_themes_memory *x = (t_themes_memory *)pd_new(themes_memory_class);
// first is for bangs (to let this external play in realtime
//x->l_out = outlet_new(&x->x_obj, &s_list);
x->bangs_out = outlet_new(&x->x_obj, gensym("bang"));
// this outputs lists of events
x->list_out = outlet_new(&x->x_obj, "symbol");
// this outputs info on the last detected rhythm
x->info_out = outlet_new(&x->x_obj, "symbol");
// inlet for rhythms in the form of lists
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("rhythm_in"));
x->x_clock = clock_new(x, (t_method)rhythms_tick);
x->seq_initialized = 0;
rhythm_memory_create(&(x->themes_memory));
start_measure(x);
return (x);
}
// debugging function
void crash(t_themes_memory *x)
{
int *a;
a = malloc(sizeof(int));
a[9999999999999999999] = 1;
}
void themes_memory_setup(void)
{
themes_memory_class = class_new(gensym("themes_memory"), (t_newmethod)themes_memory_new,
(t_method)themes_memory_free, sizeof(t_themes_memory), CLASS_DEFAULT, A_GIMME, 0);
class_addbang(themes_memory_class, (t_method)themes_memory_bang);
class_addmethod(themes_memory_class, (t_method)end_measure, gensym("measure"), 0);
class_doaddfloat(themes_memory_class, (t_method)add_event);
class_addmethod(themes_memory_class, (t_method)crash, gensym("crash"), 0);
// the user asks for a rhythm
class_addmethod(themes_memory_class, (t_method)ask_rhythm, gensym("rhythm_out"),
A_GIMME, 0);
// adds a rhythm passing it as a list of floats
class_addmethod(themes_memory_class, (t_method)add_rhythm, gensym("rhythm_in"),
A_GIMME, 0);
// builds a variation of a given rhythm
class_addmethod(themes_memory_class, (t_method)variation, gensym("variation"),
A_GIMME, 0);
}
--- NEW FILE: themes_memory.vcproj ---
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="themes_memory"
ProjectGUID="{DBC75D2A-816A-4C0A-8FE7-2016518D2D19}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/export:themes_memory_setup /dll"
AdditionalDependencies="pd.lib"
OutputFile="$(OutDir)/themes_memory.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="../"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/frankenstein.pdb"
SubSystem="0"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="TRUE"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/frankenstein.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File
RelativePath="common.c">
</File>
<File
RelativePath="themes_memory.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc">
<File
RelativePath="common.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
- Previous message: [PD-cvs] abstractions/pureunity README, 1.6, 1.7 TODO, 1.2, 1.3 ChangeLog, 1.2, 1.3 main.pd, 1.3, 1.4
- Next message: [PD-cvs] pd/src d_fft.c,1.2.4.1.2.1,1.2.4.1.2.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list