#### Analyze audio file from table - Detect BPM and/or amplitude within a spectrum

@whale-av Thanks for replying!

Agreed, it is not a very simple thing to set up in Pd. However, since BPM-calculation of an audio file isn't terribly complex to get going in more traditional syntax (We've looked at rough prototypes of it in C#) i'm honestly surprised that I can't find more examples of it in Pd.

Things that I can get immediately upon loading an audio file to an array is basic info such as sample size and length of file in samples. Using these it should be fairly simple to get a length of the file in MS, which in turn should allow me to at least guesstimate a BPM. From there, being able to use FFT, bandpassing or maybe even fiddle~ to distinguish between different forms of instruments playing would just be a huge bonus. (Again, even FFT seems to be easier to set up in C# than what I've had success with in Pd.) For the sake of argument you could imagine that this would be used for a very basic rhythm game such as the likes of Guitar Hero.

If all we wanted to do was to beatmatch to pre-defined music tracks then we'd be set - i'd just use a form of a click track derived from the actual track like you suggested, write that to an array that spans the length of the song and then read back from it during playtime. Being able for users to load the own music would give such an increased value though.

We've been inspired by the VR game Audioshield, in which the BPM tracking on user-defined music works "fairly well".

Audioshield:

Again, thanks for engaging! Hopefully this could at least lead to some cool discussions

#### Convert a video into sound

Finally i found this related thread about video to audio conversion, i also have a related question and want to know if you know the solution. Yesterday, i find this tutorial about video conversion and it recommended me to download their video converter to convert MP4 format. In this tutorial, as you can see ([http://www.videoconverterfactory.com/tips/hd-crack.html) it claimsthat the video size can be compressed after conversion . However, after downloaded the program and converted my MP4 video file to mp3 audio, the size should get much bigger, around 30 percent larger than the original video while the audio quality stayed the same. Do you know what might cause this weird thing?

#### Suggestions on programming a video-controlled interactive system

Hello there.

I haven't done a lot of pd systems involving visuals, so I'm unsure of how evolved and documented the video-oriented side of PD is.

I'm in the very early stages of experimenting with what will eventually be an interactive system controlling physical parameters.

Right now, the idea in its core is this: A pd patch reads/scans a pre-recorded or live-input video source and based on what values can be extracted in realtime (or offline), these values will control various stages of the system.

At this stage I am not interested in synthesising visuals with GEM, but to "read" the information of a real-time video source. Something along the lines of movement, colour, contrasts, the ratio of light versus dark in the video, maybe scans of grain, framerate and so forth.

Are there any places I can find documentation on similar systems? I imagine I would have to incorporate a second application of sorts, a program to analyse and output the video data that I could then patch into PD and use as control-values.

Any and all information and suggestions will be appreciated.

Thank you.

Mh.

#### Playing sound files based on numbers/sets of numbers?

@Alexita Hello again. You don't absolutely need abstractions, but they make the building of the patch much quicker (a lot less typing). Putting 2 or 3 digit numbers is more difficult.... I will think about that. Stopping with a second enter will be possible.

The patch is already able to play only a selection of the 17 tracks...... although they must all "exist".

If the tracks are in the same folder as the patch the paths are not necessary, so it becomes much more portable.

But portable on a flash drive means putting Pd on the flash drive as well (in a portable format), and the tracks as well........ so a big enough flash drive. I am assuming that the computer the flash drive will be plugged into will not have Pd already installed. Will it always be a PC? or a Mac? or Linux? Or will it have some flavour of Pd installed already? That would be useful.

It will be much easier to build with abstractions if the tracks are named 1.wav, 2.wav, 3........ 17.wav.

What are the two, three and four digit numbers? How do they choose between the 17 files? 1-17 is easily understandable. Can you post a "table" of what they should be........ like?

1 - 33

2 - 41

3 - 123

4 - 18

5 - 6072

or is there supposed to be some sort of a random function...... where you are not really selecting at all? The task makes no sense to me with this requirement (at the moment). You would need to remember the 17 large numbers!

I will post an abstraction version, assuming all of the tracks in the same folder. A "sub" folder is easy as well (for the tracks).

............................ 17 tracks with loop abstractions.zip ...... now in "loop" mode already when it starts.

I have added metering, just for fun.

You must put 17 tracks named 1.wav ... 17.wav in the same folder.

The keyboard numbers 1 - 9 will work (for the moment, and for the first 9 tracks)

David.

PS..... looking for a pattern...... anyone?

Assuming...... only keys 1-9 or 0-9 used.

Of course! It's easy......... if 0 is not allowed

2 digits..... minimum total 2 max 18........ range 17

3 digits......minimum total 3 max 27........ divide by 1.5 and subtract (about) 1........ range 17

4 digits......minimum total 4 max 36........ divide by 2 and subtract (about) 1........ range 17

Need to round up or down..... look at results.....

For now.... 17 tracks loop enter start stop.zip starts and stops (stops tracks dead.... should the sequence complete?) with enter.

David.

#### Matrices and reallocating memory

I tried to find all my errors, corrected them and now it seemes to work.

(The method *init_array* is still missing a check if allocations failed.)

Do I really have to free the colums before reallocating the rows? Isn't it the other way around?

```
#include "m_pd.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
static t_class *average_tilde_class;
typedef struct _average_tilde {
t_object x_obj;
t_int len_avg;
t_int block_size;
t_int pos;
t_sample **sampel_arr;
t_sample *avg;
t_inlet* x_in;
t_outlet* x_out;
} t_average_tilde;
void average_tilde_free (t_average_tilde *x)
{
// Deallocate rows
for (int i = 0; i < x->len_avg; ++i)
free(x->sampel_arr[i]);
// Deallocate columns
free(x->sampel_arr);
// Deallocate avg
free(x->avg);
}
t_int *average_tilde_perform(t_int *w)
{
t_average_tilde *x = (t_average_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
//int block = (int)(w[4]);
t_sample val;
for (int n = 0; n < x->block_size; n++) {
x->avg[n] -= x->sampel_arr[x->pos][n];
val = in[n] / x->block_size;
x->avg[n] += val;
x->sampel_arr[x->pos][n] = val;
*out++ = x->avg[n];
}
x->pos++;
if (x->pos == x->len_avg) x->pos = 0;
return (w + 5);
}
void resize_avg_array(t_average_tilde *x, int len_avg_new)
{
int i,j;
int success = 1;
t_sample **temp = NULL;
t_sample *temp2 = NULL;
do {
success = 1;
// Allocate the columns
temp = realloc(temp, len_avg_new * sizeof(t_sample*));
if (temp == NULL) {
len_avg_new--;
free(temp);
success = 0;
}
else {
// The new column's pointer must be initialised to NULL
for (i = 0; i < len_avg_new; i++)
temp[i] = NULL;
// Allocate the rows
for (i = 0; i < len_avg_new; i++) {
temp[i] = realloc(temp[i], x->block_size * sizeof(t_sample));
if (temp[i] == NULL) {
len_avg_new--;
success = 0;
break;
}
else {
// Initialize the element(s)
for (j = 0; j < x->block_size; j++)
temp[i][j] = 0.0;
}
}
if (success == 1) {
// Initialize avg-array
temp2 = realloc(temp2, x->block_size * sizeof(t_sample));
if (temp2 == NULL) {
len_avg_new--;
success = 0;
free(temp2);
}
else {
// Initialize the element(s)
for (i = 0; i < x->block_size; i++)
temp2[i] = 0.0;
}
if (success == 1) {
// Deallocate rows
for (i = 0; i < x->len_avg; ++i)
free(x->sampel_arr[i]);
// Deallocate columns
free(x->sampel_arr);
// Copy temps to arrays
x->len_avg = len_avg_new;
x->sampel_arr = temp;
free(x->avg);
x->avg = temp2;
x->pos = 0;
}
}
}
} while (success = 0 && len_avg_new > 0);
if (success = 0) {
post("length of avg-vector stayed at %i samples", x->len_avg);
}
}
void average_tilde_dsp(t_average_tilde *x, t_signal **sp)
{
x->block_size = sp[0]->s_n;
float arr_size = sizeof(x->sampel_arr) / sizeof(x->sampel_arr[0][0]);
if (x->block_size * x->len_avg != arr_size)
resize_avg_array(x, 10);
dsp_add(average_tilde_perform, 4,
x,
sp[0]->s_vec,
sp[1]->s_vec,
sp[0]->s_n);
}
void set_len_avg(t_average_tilde *x, t_floatarg f)
{
if ((int)f > 0)
resize_avg_array(x, f);
}
void init_array(t_average_tilde *x)
{
int i = 0, j = 0;
// Allocate the columns
x->sampel_arr = (t_sample**)calloc(x->len_avg, sizeof(t_sample*));
// Allocate the rows
for (i = 0; i < x->len_avg; i++)
x->sampel_arr[i] = (t_sample*)calloc(x->block_size, sizeof(t_sample));
// Initialize the element(s)
for (i = 0; i < x->len_avg; i++)
for (j = 0; j < x->block_size; j++)
x->sampel_arr[i][j] = 0.0;
// Initialize avg-array
x->avg = realloc(x->avg, x->block_size * sizeof(t_sample));
for (j = 0; j < x->block_size; j++)
x->avg[j] = 0.0;
}
void *average_tilde_new(t_floatarg f)
{
t_average_tilde *x = (t_average_tilde *)pd_new(average_tilde_class);
// initialize values with defaults
x->len_avg = ((int)f > 0) ? (int)f : 10;
x->block_size = 64;
x->pos = 0;
init_array(x);
x->x_out = outlet_new(&x->x_obj, &s_signal);
return (void *)x;
}
void init_average(void) {
average_tilde_class = class_new(gensym("r_avg~"),
(t_newmethod)average_tilde_new,
(t_method)average_tilde_free,
sizeof(t_average_tilde),
CLASS_DEFAULT,
A_DEFFLOAT, 0);
class_addmethod(average_tilde_class,
(t_method)average_tilde_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(average_tilde_class, t_average_tilde, len_avg);
class_addfloat(average_tilde_class, set_len_avg);
}
void helloworld_setup(void) {
init_average();
}
```

EDIT: Corrected some logical errors in the code.

The variable *success* has to be set to 1 in each do while loop

The arrays *x->sampel_arr* and *x->avg* have to be freed inside the do while loop

#### Matrices and reallocating memory

**EDIT:**

**The original thread title was: Interrupt/disable perform method while reallocating memory
I changed it, as it was based on searching for a solution caused by faulty code.
After discarding my code the topic of the thread got a new direction.**

Hi,

I try to write an external, which calculates the averages of samples at their positions over time.

For example:

With average time = 3:

3 signals given over 3 blocks: [1, 3, 5 ...], [2, 4, 6...],[1, 3, 5...] should result in [1.33, 3,33, 5,33, ...]

The example code below works, as long as I don't try to resize the average time to a lower value while dsp is running.

On changing the average time while dsp is on, my code reallocates memory for the average vector. The result is an exception in the perform method in line 53 *x->avg[n] -= x->sampel_arr[x->pos][n];*

The commented lines using x->busy were an attempt to use a switch. But the code of the switch is never used, so it doesn't work.

Does anybody have an idea how to bypass the perform method while memory is reallocated?

```
#include "m_pd.h"
#include <string.h>
#include <stdlib.h>
static t_class *average_tilde_class;
typedef struct _average_tilde {
t_object x_obj;
t_int len_delay;
t_int block_size;
t_int pos;
t_sample **sampel_arr;
t_float *avg;
t_int busy;
t_inlet* x_in;
t_outlet* x_out;
} t_average_tilde;
void average_tilde_free(t_average_tilde *x)
{
// Deallocate rows
for (int i = 0; i < x->len_delay; ++i)
free(x->sampel_arr[i]);
// Deallocate columns
free(x->sampel_arr);
// Deallocate avg
free(x->avg);
}
t_int *average_tilde_perform(t_int *w)
{
t_average_tilde *x = (t_average_tilde *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int block = (int)(w[4]);
/*if (x->busy == 1) {
while (block--) {
*out++ = *in++;
}
return (w + 5);
};*/
float val;
for (int n = 0; n < x->block_size; n++) {
x->avg[n] -= x->sampel_arr[x->pos][n];
val = in[n] / x->block_size;
x->avg[n] += val;
x->sampel_arr[x->pos][n] = val;
*out++ = x->avg[n];
}
x->pos++;
if (x->pos == x->len_delay) x->pos = 0;
return (w + 5);
}
void resize_avg_array(t_average_tilde *x)
{
int i,j;
/*post("resize");
x->busy = 1;*/
// Allocate the columns
x->sampel_arr = (int**)realloc(x->sampel_arr, x->len_delay * sizeof(int*));
/*if (x->sampel_arr == NULL)
post("error");*/
// The new column's pointer must be initialised to NULL
for (i = 0; i < x->len_delay; i++)
x->sampel_arr[i] = NULL;
// Allocate the rows
for (i = 0; i < x->len_delay; i++) {
x->sampel_arr[i] = (float*)realloc(x->sampel_arr[i], x->block_size * sizeof(float));
/*if (x->sampel_arr == NULL)
post("error");*/
}
// Initialize the element(s)
for (i = 0; i < x->len_delay; i++)
for (j = 0; j < x->block_size; j++)
x->sampel_arr[i][j] = 0.0;
// Allocate avg-array
x->avg = realloc(x->avg, x->block_size * sizeof(float));
/*if (x->avg == NULL)
post("error");*/
// Initialize avg-array
for (i = 0; i < x->block_size; i++)
x->avg[i] = 0.0;
/*x->busy = 0;
post("resize2");
post(" ");*/
}
void average_tilde_dsp(t_average_tilde *x, t_signal **sp)
{
x->block_size = sp[0]->s_n;
float arr_size = sizeof(x->sampel_arr) / sizeof(x->sampel_arr[0][0]);
if (x->block_size * x->len_delay != arr_size)
resize_avg_array(x);
dsp_add(average_tilde_perform, 4,
x,
sp[0]->s_vec,
sp[1]->s_vec,
sp[0]->s_n);
}
void set_len_delay(t_average_tilde *x, t_floatarg f)
{
if ((int)f > 0) x->len_delay = (int)f;
resize_avg_array(x);
}
void init_array(t_average_tilde *x)
{
int i = 0, j = 0;
// Allocate the columns
x->sampel_arr = (int**)calloc(x->len_delay, sizeof(int*));
// Allocate the rows
for (i = 0; i < x->len_delay; i++)
x->sampel_arr[i] = (float*)calloc(x->block_size, sizeof(float));
// Initialize the element(s)
for (i = 0; i < x->len_delay; i++)
for (j = 0; j < x->block_size; j++)
x->sampel_arr[i][j] = 0.0;
// Initialize avg-array
x->avg = realloc(x->avg, x->block_size * sizeof(float));
for (j = 0; j < x->block_size; j++)
x->avg[j] = 0.0;
}
void *average_tilde_new(t_floatarg f)
{
t_average_tilde *x = (t_average_tilde *)pd_new(average_tilde_class);
// initialize values with defaults
x->len_delay = ((int)f > 0) ? (int)f : 10;
x->block_size = 64;
x->pos = 0;
init_array(x);
x->busy = 0;
x->x_out = outlet_new(&x->x_obj, &s_signal);
return (void *)x;
}
void init_average(void) {
average_tilde_class = class_new(gensym("r_avg~"),
(t_newmethod)average_tilde_new,
(t_method)average_tilde_free,
sizeof(t_average_tilde),
CLASS_DEFAULT,
A_DEFFLOAT, 0);
class_addmethod(average_tilde_class,
(t_method)average_tilde_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(average_tilde_class, t_average_tilde, len_delay);
class_addfloat(average_tilde_class, set_len_delay);
}
void helloworld_setup(void) {
init_average();
}```
// The code for reallocation is taken from here:
// http://hesham-rafi.blogspot.de/2009/02/resize-2d-matrix-using-realloc.html
```

#### send list to outlet in external

Thanks for your advise about the clock method. As this is quite important, this information should be given somewhere (In externs/dspobj~.c which comes with pd for example)

What are own inlets? Is a second inlet~ already an own inlet?

Can you point me to the source of [pack]? (Couldn't find a file "pack.c" or similar in pd's repository on github.)

Do I have to free memory I allocated myself with malloc?

(I just started with C (coming from Python), so I'm still unsure about how things work exactly.)

To leave a working example, here's my corrected code:

```
#include "m_pd.h"
static t_class *maximum_tilde_class;
typedef struct _maximum_tilde {
t_object x_obj;
t_float f;
t_clock* m_clock;
t_inlet* x_in1;
t_outlet* f_out;
t_atom at[2];
} t_maximum_tilde;
t_int maximum_tilde_tick(t_maximum_tilde *x) {
outlet_list(x->f_out, &s_list, 2, x->at);
}
t_int *maximum_tilde_perform(t_int *w)
{
t_maximum_tilde *x = (t_maximum_tilde *)(w[1]);
t_sample *in1 = (t_sample *)(w[2]);
int n = (int)(w[3]);
float max[] = { 0,-1 };
float abs_val = 0;
for (int i = 0; i < n; i++) {
abs_val = fabs(in1[i]);
if (abs_val > max[0]) {
max[0] = abs_val;
max[1] = i;
}
}
SETFLOAT(x->at, (t_float)max[0]);
SETFLOAT(x->at + 1, (t_float)max[1]);
clock_set(x->m_clock, 0.f);
return (w + 4);
}
void maximum_tilde_dsp(t_maximum_tilde *x, t_signal **sp)
{
dsp_add(maximum_tilde_perform, 3,
x,
sp[0]->s_vec,
sp[0]->s_n);
}
void *maximum_tilde_new(t_floatarg f)
{
t_maximum_tilde *x = (t_maximum_tilde *)pd_new(maximum_tilde_class);
x->f_out = outlet_new(&x->x_obj, &s_list);
x->m_clock = clock_new(x, (t_method)maximum_tilde_tick);
return (void *)x;
}
void init_maximum(void) {
maximum_tilde_class = class_new(gensym("max~"),
(t_newmethod)maximum_tilde_new,
0,
sizeof(t_maximum_tilde),
CLASS_DEFAULT,
A_DEFFLOAT, 0);
class_addmethod(maximum_tilde_class,
(t_method)maximum_tilde_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(maximum_tilde_class, t_maximum_tilde, f);
}
void helloworld_setup(void) {
init_maximum();
}
```

#### send list to outlet in external

Hi,

I try to write an external, which sends a list to an outlet.

The following code is an example of calculating the maximum of a signal and send the maximum and it's index to the outlet.

But line 30 *outlet_float(x->f_out, (max[0], max[1]) );* does only send one value to the outlet.

How can I achieve to send lists?

Thanks for help in advance,

Xaver

```
#include "m_pd.h"
static t_class *maximum_tilde_class;
typedef struct _maximum_tilde {
t_object x_obj;
t_sample d;
t_inlet*x_in1;
t_outlet*f_out;
} t_maximum_tilde;
t_int *maximum_tilde_perform(t_int *w)
{
t_maximum_tilde *x = (t_maximum_tilde *)(w[1]);
t_sample *in1 = (t_sample *)(w[2]);
int n = (int)(w[3]);
float max[] = { 0,-1 };
float abs_val = 0;
for (int i = 0; i < n; i++) {
abs_val = fabs(in1[i]);
if (abs_val > max[0]) {
max[0] = abs_val;
max[1] = i;
}
}
outlet_float(x->f_out, (max[0], max[1]) );
return (w + 4);
}
void maximum_tilde_dsp(t_maximum_tilde *x, t_signal **sp)
{
dsp_add(maximum_tilde_perform, 3,
x,
sp[0]->s_vec, data forum
sp[0]->s_n);
}
void maximum_tilde_free(t_maximum_tilde *x)
{
inlet_free(x->x_in1);
}
void *maximum_tilde_new(t_floatarg f)
{
t_maximum_tilde *x = (t_maximum_tilde *)pd_new(maximum_tilde_class);
x->f_out = outlet_new(&x->x_obj, &s_list);
return (void *)x;
}
void init_maximum(void) {
maximum_tilde_class = class_new(gensym("max~"),
(t_newmethod)maximum_tilde_new,
0,//(t_method)maximum_tilde_free,
sizeof(t_maximum_tilde),
CLASS_DEFAULT,
A_DEFFLOAT, 0);
class_addmethod(maximum_tilde_class,
(t_method)maximum_tilde_dsp, gensym("dsp"), 0);
CLASS_MAINSIGNALIN(maximum_tilde_class, t_maximum_tilde, d);
}
void helloworld_setup(void) {
init_maximum();
}
```

#### Issues with playing two videos at the same time

Hey Guys,

When I try to play two different videos with a video-player patch at the same time (mp4, mov, mpeg). The video is loaded and gets stucked, plus there is this message: sgset-channeldevice return error 9408 / could not set SG rect

Nothing happens, while PD continues trying to start the videos. But with quite old .mov files (both, the new and the old uses h.264 codec) the videos will be played. They are just of no use for me.

I am using pd 0.43.4-extended on an i mac (el capitano, 2,4ghz, intel core 2 duo, 8gb) . I used another video-player patch to play a single and every format was played correctly.

Did anyone had similiar issues and could solve them?

best,

bewegtbild

#### Syncing issues with audio/video (have searched github to no avail)

@musicproject Hello Rachel....... I played around this morning and watched the video to the end.

As I thought earlier the audio player is playing faster than the video. That can be corrected automatically using the extended version of Pd...... but to keep things simple you must resample your audio tracks at 48000Hz to match the video samplerate and the samplerate of your soundcard. If you have no audio editor that can do this I can upload and send you a link..... at the moment your videos are at 48kHz and your audio tracks at 44.1kHz.

Also...... here is a simpler audio player that might help with the cpu load....... fix37.zip

David.