<?xml version="1.0" encoding="UTF-8"?>
	<rss version="2.0"
		xmlns:content="http://purl.org/rss/1.0/modules/content/"
		xmlns:wfw="http://wellformedweb.org/CommentAPI/"
		xmlns:dc="http://purl.org/dc/elements/1.1/"
		xmlns:atom="http://www.w3.org/2005/Atom"

			>

	<channel>
		<title>Cycling 74  &#187;  Topic: Accessing a buffer in an MSP external?</title>
		<atom:link href="http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/feed" rel="self" type="application/rss+xml" />
		<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/feed</link>
		<description></description>
		<pubDate>Wed, 19 Jun 2013 14:38:54 +0000</pubDate>
		<generator>http://bbpress.org/?v=2.2.4</generator>
		<language></language>

		
														
					
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-47759</guid>
					<title><![CDATA[Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-47759</link>
					<pubDate>Wed, 13 Jan 2010 12:43:58 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p>Hi</p>
<p>I&#8217;m fairly experienced with Max/MSP but I have just started out with creating externals. Despite having some experience with C previously it has completely got my head in a twist.</p>
<p>I&#8217;ve been building a Phase Vocoder in Max which is fine. However I&#8217;ve gone on to try and add a Spectral Delay which requires building an external. Basically I need to know the best way to go about manipulating my FFT data in the external. Do I need to run the FFT data into a buffer inside Max and then access the buffer separately in the external? Or is it best to run the FFT data into the external and then buffer it for delays?</p>
<p>If it will be better to access the buffer how do I go about doing that? Having looked at the SDK help I haven&#8217;t seen a way of taking in that data.</p>
<p>Thanks for the help.<br />
SR</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171757</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171757</link>
					<pubDate>Wed, 13 Jan 2010 13:45:38 +0000</pubDate>
					<dc:creator>Eric Lyon</dc:creator>

					<description>
						<![CDATA[
						<p>It is relatively easy to write a spectral delay processor using the pfft~ system, so there is no need to write an external for this purpose. When it is necessary to keep data around for significantly longer (see my residency~ external in FFTease) I have generally found it more convenient to keep the data in an internal buffer, rather than using a Max/MSP buffer. However I have also implemented algorithms that use Max/MSP buffers for special situations (see residency_buffer~ in FFTease). </p>
<p>In any case, it is certainly worth learning how to write externals to solve problems that are difficult to solve in Max/MSP itself. (I&#8217;m writing a book on this subject right now.)</p>
<p>Good luck,</p>
<p>Eric</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171758</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171758</link>
					<pubDate>Wed, 13 Jan 2010 13:47:37 +0000</pubDate>
					<dc:creator>mudang</dc:creator>

					<description>
						<![CDATA[
						<p>If you&#8217;re working inside pfft~ you can get the fft data straight through an audio inlet of your external. Vector size will be half the windowsize.<br />
It&#8217;s easy as that; no need for a buffer.</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171759</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171759</link>
					<pubDate>Wed, 13 Jan 2010 14:43:33 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p>@mudang</p>
<p>I was just thinking that it would be easier to handle in a buffer since then each element will represent one frame of the FFT. Meaning for each element of the buffer a delay time from a separate buffer can be attached.</p>
<p>Great thanks for the help guys.<br />
SR</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171760</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171760</link>
					<pubDate>Wed, 13 Jan 2010 15:04:56 +0000</pubDate>
					<dc:creator>Brad Garton</dc:creator>

					<description>
						<![CDATA[
						<p>Although it&#8217;s pretty easy to set up pointers to/from max/msp buffers, I think it makes more sense conceptually for data you are processing within your external to set up the buffer also within the external.  Of course, if your intent is to share data among objects then maybe use a max/msp buffer.</p>
<p>Have you checked out John Gibson&#8217;s spectral delay externals?</p>
<p><a href="http://www.john-gibson.com/" rel="nofollow">http://www.john-gibson.com/</a></p>
<p>(go to &#8216;software&#8217;).  They&#8217;re really impressive.</p>
<p>brad</p>
<p><a href="http://music.columbia.edu/~brad" rel="nofollow">http://music.columbia.edu/~brad</a></p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171761</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171761</link>
					<pubDate>Wed, 13 Jan 2010 15:21:29 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p>Those John Gibson ones were my inspiration! Although I doubt mine will be anywhere near that good anytime soon. That&#8217;s the aim though.</p>
<p>I think i&#8217;m going to go with creating the buffer in the external and then create another alongside it for delay times and count them round together.</p>
<p>SR</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171762</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171762</link>
					<pubDate>Wed, 13 Jan 2010 18:01:13 +0000</pubDate>
					<dc:creator>pid</dc:creator>

					<description>
						<![CDATA[
						<p>@Eric: when will your book be out?! i want to buy it now!</p>
<p><a href='http://cycling74.com/forums/users/shatter_resistant/' rel='nofollow' class='bbp-mention-link shatter_resistant'>@shatter_resistant</a>: best of luck, i&#8217;ll test anything you do (!). i love the john gibson&#8217;s too but upset no panning controls inside the externals. will yours pan?</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171763</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171763</link>
					<pubDate>Wed, 13 Jan 2010 19:20:53 +0000</pubDate>
					<dc:creator>Pierre Alexandre Tremblay</dc:creator>

					<description>
						<![CDATA[
						<p>[blockquote] @Eric: when will your book be out?! i want to buy it now! [/blockquote]</p>
<p>+1</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171764</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171764</link>
					<pubDate>Wed, 13 Jan 2010 21:54:53 +0000</pubDate>
					<dc:creator>AlexHarker</dc:creator>

					<description>
						<![CDATA[
						<p>&#8220;It is relatively easy to write a spectral delay processor using the pfft~ system, so there is no need to write an external for this purpose.&#8221;</p>
<p>This is kind of true &#8211; there are index~ based solutions that are conceptually quite straightforward, but a word of warning in tapin~/tapout~ or delay~ based solutions (I haven&#8217;t tried the later but I assume it should work). These are a bit more complex, due to an unexpected extra sample of delay (for me at least) when setting the delay times using signals (which you would need to do in this case) &#8211; this came up when I was checking someone else&#8217;s spectral delay patch about a year ago, and makes these things a bit nasty &#8211; so first thing is I&#8217;d use count~ and index~ or something like that if you get a max solution.</p>
<p>There are other reasons for hard coding &#8211; including the inefficiency and lower accuracy of the current pfft~ fft routines as compared to the apple vDSP ones (if you are on a mac of course) and possibly dealing with more complex algorithms becoming simpler.</p>
<p>I seem to remember that John Gibson&#8217;s spectral delay (which I thought excellent in terms of code clarity and thoroughness) does not phase accumulate at all, meaning that when the delay times are changing the results can be choppy. In order to get a smoother sound for changing delay times you need to phase accumulate (standard phase vocoder fare&#8230;), although this leads to the potentially more problematic situation of having phase smearing and drift etc. etc. As a compromise, when I wrote my spectral delay external probably about 4 years ago now I used a hybrid technique, where I slowly reset the accumulation to zero over time, so that the delay time transitions are smooth, but eventually you return to the correct input phases &#8211; at which point you stop phase accumulating so as to conserve CPU. You can set the rate of this correction to choose a compromise between choppy transitions and rate of return to phase coherence as you desire&#8230;</p>
<p>This topic has come up before here as well &#8211; so there should be some old posts around about this. If the code is of interest to anyone I can post it, although it&#8217;s not as pretty as John Gibson&#8217;s, and it lacks proper denormal handling at present. However, in essence it&#8217;s a ring buffer with a cartesian phase vocoder.</p>
<p>As regarding MSP or internal buffers I&#8217;d say only use an msp buffer for the actual delay if you can see some value in allowing users to interact with the buffer in their own way &#8211; I&#8217;d say in this case you probably wouldn&#8217;t want this &#8211; so just allocate yourself some memory and store your data internally &#8211; however, you might have a different idea.</p>
<p>Regards,</p>
<p>Alex</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171765</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171765</link>
					<pubDate>Thu, 14 Jan 2010 10:31:45 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p>@ Alex that&#8217;d be great if I could have a look at your code, if that&#8217;s no trouble.</p>
<p>You make a good point about a Max solution, it just seems to unstable to work really effectively. So I&#8217;m going to stick with my external.</p>
<p>@pid I hadn&#8217;t thought about panning yet. I&#8217;m on a time limit so it might happen eventually but I wouldn&#8217;t be hopeful in the near future.</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171766</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171766</link>
					<pubDate>Thu, 14 Jan 2010 11:54:09 +0000</pubDate>
					<dc:creator>AlexHarker</dc:creator>

					<description>
						<![CDATA[
						<p>OK &#8211; here it is &#8211; it&#8217;s all vanilla C and not the neatest code at that (also slightly under-commented) &#8211; If I did this now it&#8217;d be a lot neater and more concise &#8211; but as mentioned earlier, this code is at least 4 years old &#8211; I don&#8217;t think I&#8217;ve touched it in that time :</p>
<p>For intel / pc you need a decent denorm solving strategy for the feedback part (which this doesn&#8217;t have &#8211; was written under PPC, and I&#8217;ve run it under intel, but not in a CPU critical situation &#8211; it clearly does spike on tails due to feedback). I&#8217;ve taken to just turning off denormals these days on the mac platform, as floating point math is done on the vector unit (unless you explicitly tell the compiler not to I think), and the vector unit has the option to turn denormals off (flush to zero &#8211; FTZ &#8211;  and denormals are zero flags &#8211; DAZ &#8211; respectively) &#8211;  this is faster and easier than other methods&#8230;.</p>
<p>Also the interpolation between accumulated coords and straight out the buffer cartesian coords is done linearly here, which is not the best &#8211; there may be a better way of doing this. THe other problem for spectral delay I&#8217;ve never solved adequately is the fractional frame delay (for different delays across the spectrum). I think some form of cubic interpolation on the cartesian coords may work well, but the problem is a bit complex for me &#8211; however, the limitation of only exact frames of delay may or may not be a problem depending on your purposes.</p>
<p>Do ask if anything is not clear&#8230;.</p>
<p>Alex.</p>
<p>#include <ext .h><br />
#include <z_dsp .h><br />
#include &#8220;r_pfft.h&#8221;</z_dsp></ext></p>
<p>#define TWOPI 6.28318530717958647692<br />
void *this_class;</p>
<p>typedef struct _SpectralDelay<br />
{<br />
    t_pxobject x_obj;<br />
	t_pfftpub *x_pfft;</p>
<p>    float *FFTbuffer_real, *FFTbuffer_imag, *FFT_Buffer;</p>
<p>	long pfftvectsize;</p>
<p>    char MemAlloc;<br />
    long currentpos, maxpos, maxframes;<br />
    int PhaseMode;<br />
    float Slide;<br />
    float PerFrame;<br />
    float Ramp;</p>
<p>    long *delaytimes;<br />
    // float *delaytimesfract;<br />
	float *feedbacklevels;</p>
<p>    void *f_proxy;<br />
    void *f_proxy2;<br />
    long f_inletNumber;<br />
    long f_inletNumber2;</p>
<p>} t_SpectralDelay;</p>
<p>void *SpectralDelay_new(long maxframes);<br />
void SpectralDelay_free(t_SpectralDelay *x);<br />
void SpectralDelay_list (t_SpectralDelay *x, t_symbol *msg, short argc, t_atom *argv);<br />
void SpectralDelay_slide(t_SpectralDelay *x, double Slide);<br />
void SpectralDelay_rampsmooth(t_SpectralDelay *x, double PerFrame);<br />
void SpectralDelay_dsp(t_SpectralDelay *x, t_signal **sp, short *count);<br />
t_int *SpectralDelay_perform(t_int *w);<br />
void SpectralDelay_assist(t_SpectralDelay *x, void *b, long m, long a, char *s);</p>
<p>t_symbol *ps_spfft;</p>
<p>void main(void)<br />
{<br />
    setup((t_messlist **)&#038;this_class, (method) SpectralDelay_new, (method)SpectralDelay_free, (short)sizeof(t_SpectralDelay), 0L, A_DEFLONG, 0);<br />
    addmess((method)SpectralDelay_dsp, &#8220;dsp&#8221;, A_CANT, 0);<br />
    addmess ((method)SpectralDelay_list, &#8220;list&#8221;, A_GIMME, 0);<br />
    addmess ((method)SpectralDelay_slide, &#8220;slide&#8221;, A_DEFFLOAT, 0);<br />
    addmess ((method)SpectralDelay_rampsmooth, &#8220;rampsmooth&#8221;, A_DEFFLOAT, 0);<br />
    addmess ((method)SpectralDelay_assist, &#8220;assist&#8221;, A_CANT, 0);<br />
    ps_spfft = gensym(&#8220;__pfft~__&#8221;);<br />
    dsp_initclass();<br />
}</p>
<p>void SpectralDelay_free(t_SpectralDelay *x)<br />
{<br />
	dsp_free(&#038;x->x_obj);</p>
<p>	if (x->FFT_Buffer) free (x->FFT_Buffer);<br />
    if (x->delaytimes) free (x->delaytimes);<br />
    free (x->feedbacklevels);<br />
	if (x->FFTbuffer_real) free (x->FFTbuffer_real);<br />
	if (x->FFTbuffer_imag) free (x->FFTbuffer_imag);</p>
<p>    freeobject((t_object *) x->f_proxy2);<br />
    freeobject((t_object *) x->f_proxy);<br />
}</p>
<p>void SpectralDelay_slide(t_SpectralDelay *x, double Slide)<br />
{<br />
	x->PhaseMode = 1;<br />
	if ( Slide >= 0 &#038;&#038; Slide < = 1)<br />
		x->Slide = (float) Slide;<br />
}</p>
<p>void SpectralDelay_rampsmooth(t_SpectralDelay *x, double PerFrame)<br />
{<br />
	x->PhaseMode = 0;<br />
	if ( PerFrame >= 0 &#038;&#038; PerFrame < = 1)<br />
		x->PerFrame = (float) PerFrame;<br />
}</p>
<p>void *SpectralDelay_new(long maxframes)<br />
{<br />
    t_SpectralDelay *x = (t_SpectralDelay *)newobject(this_class);</p>
<p>    x->f_proxy2 = proxy_new(x, 4 ,&#038;x->f_inletNumber2);<br />
    x->f_proxy = proxy_new(x, 3 ,&#038;x->f_inletNumber);</p>
<p>	x->x_pfft = (t_pfftpub *)ps_spfft->s_thing;							// Find pfft vectsize<br />
    int pfftvectsize = 0;<br />
    if (x->x_pfft)<br />
    	pfftvectsize = x->x_pfft->x_fftsize / 2;<br />
	if (!pfftvectsize)<br />
		pfftvectsize = 4096;											// Default to 4096<br />
	x->pfftvectsize = pfftvectsize;</p>
<p>    dsp_setup((t_pxobject *)x, 2);<br />
    outlet_new((t_object *)x,&#8221;signal&#8221;);<br />
    outlet_new((t_object *)x,&#8221;signal&#8221;);	</p>
<p>    long *delaytimes = x->delaytimes = (long *) malloc (pfftvectsize * sizeof(long));<br />
    float *feedbacklevels = x->feedbacklevels = (float *) malloc (pfftvectsize * sizeof(float));<br />
    if (maxframes > 0 &#038;&#038; maxframes < = 10000)<br />
        x->maxframes = maxframes;<br />
    else<br />
        x->maxframes = 10;</p>
<p>    x->Slide = 0;<br />
    x->Ramp = 1;<br />
    x->PerFrame = 0;<br />
    x->PhaseMode = 0;</p>
<p>	x->FFT_Buffer = (float *) malloc(4 * pfftvectsize * sizeof (float));<br />
	float *FFT_Buffer = x->FFT_Buffer;</p>
<p>	long memoryitemsize = pfftvectsize * maxframes;<br />
	x->maxpos = memoryitemsize;</p>
<p>	float *FFTbuffer_real = x->FFTbuffer_real = (float *) malloc (memoryitemsize * sizeof(float));<br />
    float *FFTbuffer_imag = x->FFTbuffer_imag = (float *) malloc (memoryitemsize * sizeof(float));</p>
<p>	if (x->FFT_Buffer &#038;&#038; x->delaytimes &#038;&#038; x->feedbacklevels &#038;&#038; x->FFTbuffer_real &#038;&#038; x->FFTbuffer_imag) x->MemAlloc = 1;<br />
	else<br />
	{<br />
		x->MemAlloc = 0;<br />
		goto out;<br />
	}</p>
<p>	int iter;</p>
<p>	for (iter = 0; iter < memoryitemsize; iter++)<br />
		FFTbuffer_real[iter] = 0;</p>
<p>	for (iter = 0; iter < memoryitemsize; iter++)<br />
		FFTbuffer_imag[iter] = 0;	</p>
<p>	for (iter = 0; iter < 2 * pfftvectsize; iter++)<br />
		FFT_Buffer[iter] = 0;</p>
<p>	for (iter = 0; iter < pfftvectsize; iter++)<br />
	{<br />
		delaytimes[iter] = 0;<br />
		feedbacklevels[iter] = 0;<br />
	}</p>
<p>	out:</p>
<p>    x->currentpos = 0;</p>
<p>    return (x);<br />
}</p>
<p>void SpectralDelay_list (t_SpectralDelay *x, t_symbol *msg, short argc, t_atom *argv)<br />
{<br />
    long *delaytimes = x->delaytimes;<br />
    float *feedbacklevels = x->feedbacklevels;<br />
    long maxframes = x->maxframes;<br />
    long i;</p>
<p>    if (proxy_getinlet((t_object *)x) == 4)<br />
    {<br />
        for (i = 0; (i < argc) &#038;&#038; (i < x->pfftvectsize); i++)<br />
        {<br />
            switch (argv[i].a_type)<br />
            {<br />
                case A_LONG:<br />
                    feedbacklevels[i] = 0;<br />
                break;<br />
                case A_SYM:<br />
                    feedbacklevels[i] = 0;<br />
                break;<br />
                case A_FLOAT:<br />
                    if (argv[i].a_w.w_float >= -1 &#038;&#038; argv[i].a_w.w_float < = 1)<br />
                        feedbacklevels[i] = argv[i].a_w.w_float;<br />
                break;<br />
            }<br />
        }</p>
<p>    }<br />
    else<br />
    {<br />
        x->Ramp = 0;<br />
        for (i = 0; (i < argc) &#038;&#038; (i < x->pfftvectsize); i++)<br />
        {<br />
            switch (argv[i].a_type)<br />
            {<br />
                case A_LONG:<br />
                    if (argv[i].a_w.w_long >= 0 &#038;&#038; argv[i].a_w.w_long < = maxframes)<br />
                        delaytimes[i] = argv[i].a_w.w_long;<br />
                    else<br />
                        delaytimes[i] = 0;<br />
                break;<br />
                case A_SYM:<br />
                    delaytimes[i] = 0;<br />
                break;<br />
                case A_FLOAT:<br />
                    if (argv[i].a_w.w_float >= 0 &#038;&#038; argv[i].a_w.w_float < = maxframes)<br />
                        delaytimes[i] = (long) argv[i].a_w.w_float<br />
                    else<br />
                        delaytimes[i] = 0;<br />
                break;<br />
            }<br />
        }<br />
    }<br />
}</p>
<p>void SpectralDelay_dsp(t_SpectralDelay *x, t_signal **sp, short *count)<br />
{<br />
    dsp_add(SpectralDelay_perform, 6, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n, x);<br />
}</p>
<p>t_int *SpectralDelay_perform(t_int *w)<br />
{<br />
    int vectsize;<br />
    t_SpectralDelay *x;</p>
<p>    float *in1 = (float *)(w[1]);<br />
    float *in2 = (float *)(w[2]);<br />
    float *out1 = (float *)(w[3]);<br />
    float *out2 = (float *)(w[4]);<br />
    vectsize = w[5];</p>
<p>    x = (t_SpectralDelay *)(w[6]);</p>
<p>	if (x->x_obj.z_disabled || !x->MemAlloc || vectsize > x->pfftvectsize)<br />
        goto out;</p>
<p>    long *delaytimes = x->delaytimes;<br />
    float *feedbacklevels = x->feedbacklevels;<br />
    float *therealbuffer = x->FFTbuffer_real;<br />
    float *theimagbuffer = x->FFTbuffer_imag;<br />
    float outframereal, outframeimag, prevframereal, prevframeimag;<br />
	long doublevectsize = vectsize < < 1;<br />
    long maxpos = x->maxpos;<br />
    long nextpos = x->currentpos;<br />
    long iter, outframe1, outframe2;</p>
<p>	float a, b, c, d, e, f, g, h, i;<br />
	float Ramp = x->Ramp;<br />
	float Slide = x->Slide;<br />
	float PerFrame = x->PerFrame;<br />
	int PhaseMode = x->PhaseMode;<br />
	float *FFT_Buffer = x->FFT_Buffer;</p>
<p>	if (PhaseMode)<br />
		Ramp = Slide;<br />
	else<br />
	{<br />
		if (Ramp < 1)<br />
		{<br />
			Ramp = Ramp + PerFrame;<br />
			if (Ramp > 1) Ramp = 1;<br />
			x->Ramp = Ramp;<br />
		}<br />
	}</p>
<p>	if (Ramp == 1)<br />
	{<br />
		for (iter = 0; iter < vectsize; iter++)<br />
	    {<br />
	        therealbuffer[nextpos] = *in1++;<br />
	        theimagbuffer[nextpos] = *in2++;</p>
<p>	        outframe1 = nextpos &#8211; (vectsize * delaytimes[iter]);<br />
	        if (outframe1 < 0)<br />
	            outframe1 += maxpos;</p>
<p>			outframereal = therealbuffer[outframe1];<br />
			outframeimag = theimagbuffer[outframe1];</p>
<p>			FFT_Buffer[iter] = outframereal;<br />
			FFT_Buffer[iter + doublevectsize] = outframeimag;</p>
<p>	        if (delaytimes[iter] &#038;&#038; iter)		// Don&#8217;t feedback if delaytime < one frame or in the dc bin<br />
	        {<br />
	            therealbuffer[nextpos] += (feedbacklevels[iter] * outframereal);<br />
	            theimagbuffer[nextpos] += (feedbacklevels[iter] * outframeimag);<br />
	        }</p>
<p>	        *out1++ = outframereal;<br />
	        *out2++ = outframeimag;</p>
<p>	        if (++nextpos >= maxpos)<br />
	            nextpos = 0;<br />
	     }<br />
	}<br />
	else<br />
	{<br />
	    for (iter = 0; iter < vectsize; iter++)<br />
	    {<br />
	        therealbuffer[nextpos] = *in1++;<br />
	        theimagbuffer[nextpos] = *in2++;</p>
<p>	        outframe1 = nextpos &#8211; (vectsize * delaytimes[iter]);<br />
	        if (outframe1 < 0)<br />
	            outframe1 += maxpos;<br />
	        outframe2 = outframe1 &#8211; vectsize;<br />
	        if (outframe2 < 0)<br />
	            outframe2 += maxpos;</p>
<p>			outframereal = therealbuffer[outframe1];<br />
			outframeimag = theimagbuffer[outframe1];</p>
<p>			prevframereal = therealbuffer[outframe2];<br />
			prevframeimag = theimagbuffer[outframe2];</p>
<p>			// Phase Accumulate !!</p>
<p>			a = outframereal;<br />
			b = outframeimag;<br />
			c = prevframereal;<br />
			d = prevframeimag;<br />
			e = FFT_Buffer[iter];<br />
			f = FFT_Buffer[iter + vectsize];</p>
<p>			if (c == 0 &#038;&#038; d == 0) c = (float) 1;<br />
			if (e == 0 &#038;&#038; f == 0) e = (float) 1;</p>
<p>			g = ((e * c) + (f * d));<br />
			h = ((f * c) &#8211; (e * d));</p>
<p>			i = (float) 1 / sqrt((g * g) + (h * h));</p>
<p>			if (!isinf(i))<br />
			{<br />
				g = g * i;<br />
				h = h * i;<br />
			}<br />
			else<br />
			{<br />
				g = (float) 1;<br />
				h = 0;<br />
			}</p>
<p>			c = ((a * g) &#8211; (b * h));<br />
			d = ((a * h) + (b * g));</p>
<p>			c = c + (Ramp * (outframereal &#8211; c));<br />
			d = d + (Ramp * (outframeimag &#8211; d));</p>
<p>			FFT_Buffer[iter] = outframereal = c;<br />
			FFT_Buffer[iter + vectsize] = outframeimag = d;</p>
<p>	        if (delaytimes[iter] &#038;&#038; iter)											// Don&#8217;t feedback if delaytime < one frame or in the dc bin (nasty!)<br />
	        {<br />
	            therealbuffer[nextpos] += (feedbacklevels[iter] * outframereal);<br />
	            theimagbuffer[nextpos] += (feedbacklevels[iter] * outframeimag);<br />
	        }</p>
<p>	        *out1++ = outframereal;<br />
	        *out2++ = outframeimag;</p>
<p>	        if (++nextpos >= maxpos)<br />
	            nextpos = 0;<br />
	    }<br />
	 }</p>
<p>    x->currentpos = nextpos;</p>
<p>    out:<br />
    return w + 7;</p>
<p>}</p>
<p>void SpectralDelay_assist(t_SpectralDelay *x, void *b, long m, long a, char *s)<br />
{<br />
    if (m == ASSIST_OUTLET) {<br />
        switch (a) {<br />
            case 0:<br />
                sprintf(s,&#8221;(signal) FFT Real Out&#8221;);<br />
                break;<br />
            case 1:<br />
                sprintf(s,&#8221;(signal) FFT Imag Out&#8221;);<br />
                break;<br />
        }<br />
    }<br />
    else {<br />
        switch (a) {<br />
            case 0:<br />
                sprintf(s,&#8221;(signal) FFT Real In&#8221;);<br />
                break;<br />
            case 1:<br />
                sprintf(s,&#8221;(signal) FFT Imag In&#8221;);<br />
                break;<br />
			case 2:<br />
                sprintf(s,&#8221;(list) Delay Times&#8221;);<br />
                break;<br />
            case 3:<br />
                sprintf(s,&#8221;(list) Feedback Levels&#8221;);<br />
                break;<br />
        }<br />
    }<br />
}</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171767</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171767</link>
					<pubDate>Thu, 14 Jan 2010 11:55:13 +0000</pubDate>
					<dc:creator>AlexHarker</dc:creator>

					<description>
						<![CDATA[
						<p>That code was formatted when I pasted it &#8211; sorry &#8211; if you are on a mac, you can use XCode to re-indent it automatically and it&#8217;ll become a lot more readable&#8230;</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171768</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171768</link>
					<pubDate>Thu, 14 Jan 2010 11:55:36 +0000</pubDate>
					<dc:creator>AlexHarker</dc:creator>

					<description>
						<![CDATA[
						<p>Oh &#8211; and this object is designed to work within a pfft &#8211; forgot to say&#8230;.</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171769</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171769</link>
					<pubDate>Thu, 14 Jan 2010 18:26:35 +0000</pubDate>
					<dc:creator>Eric Lyon</dc:creator>

					<description>
						<![CDATA[
						<p>> @Eric: when will your book be out?! i want to buy it now!</p>
<p>Thanks for the interest! My contract specifies that the manuscript be delivered to the publisher by August 30th, 2010. So hopefully it will be out by sometime in 2011 if not before.</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171771</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171771</link>
					<pubDate>Fri, 15 Jan 2010 00:31:51 +0000</pubDate>
					<dc:creator>Eric Lyon</dc:creator>

					<description>
						<![CDATA[
						<p>Wow raja, big thanks for the enthusiasm! Hope you like the book when it comes out.</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171772</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171772</link>
					<pubDate>Fri, 15 Jan 2010 09:17:17 +0000</pubDate>
					<dc:creator>Pierre Alexandre Tremblay</dc:creator>

					<description>
						<![CDATA[
						<p>@ Eric: pressure pressure ;-)</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171773</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171773</link>
					<pubDate>Fri, 15 Jan 2010 11:04:19 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p><a href='http://cycling74.com/forums/users/alex/' rel='nofollow' class='bbp-mention-link Alex'>@Alex</a> thank you very very much. This has been a great help I can see where I&#8217;m going now (so to speak)</p>
<p><a href='http://cycling74.com/forums/users/raja/' rel='nofollow' class='bbp-mention-link Raja'>@Raja</a>&#8230;&#8230; erm&#8230;.. that&#8217;s ok????</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171774</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171774</link>
					<pubDate>Tue, 19 Jan 2010 14:34:59 +0000</pubDate>
					<dc:creator>shatter_resistant</dc:creator>

					<description>
						<![CDATA[
						<p>Alex could you please just run me through what you&#8217;re doing in this section:</p>
<p>// Phase Accumulate !!</p>
<p>a = outframereal;<br />
b = outframeimag;<br />
c = prevframereal;<br />
d = prevframeimag;<br />
e = FFT_Buffer[iter];<br />
f = FFT_Buffer[iter + vectsize];</p>
<p>if (c == 0 &#038;&#038; d == 0) c = (float) 1;<br />
if (e == 0 &#038;&#038; f == 0) e = (float) 1;</p>
<p>g = ((e * c) + (f * d));<br />
h = ((f * c) &#8211; (e * d));</p>
<p>i = (float) 1 / sqrt((g * g) + (h * h));</p>
<p>if (!isinf(i))<br />
{<br />
g = g * i;<br />
h = h * i;<br />
}<br />
else<br />
{<br />
g = (float) 1;<br />
h = 0;<br />
}</p>
<p>c = ((a * g) &#8211; (b * h));<br />
d = ((a * h) + (b * g));</p>
<p>c = c + (Ramp * (outframereal &#8211; c));<br />
d = d + (Ramp * (outframeimag &#8211; d));</p>
<p>Thanks otherwise it&#8217;s great just it&#8217;s unclear because of how you&#8217;ve coded it what is going on.<br />
SR</p>
						]]>
					</description>

					
					
				</item>

			
				<item>
					<guid>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171775</guid>
					<title><![CDATA[Re: Accessing a buffer in an MSP external?]]></title>
					<link>http://cycling74.com/forums/topic/accessing-a-buffer-in-an-msp-external/#post-171775</link>
					<pubDate>Tue, 19 Jan 2010 15:33:44 +0000</pubDate>
					<dc:creator>AlexHarker</dc:creator>

					<description>
						<![CDATA[
						<p>OK &#8211; I know roughly what&#8217;s happening here, but as I tried to do it step by step I realised it doesn&#8217;t work quite the way I thought it did&#8230;.. </p>
<p>The basic idea is a cartesian phase vocoder ith a linear interpolator at the end&#8230;.<br />
You should be able to see roughly (in order):</p>
<p>Check for divide by zero and avoid<br />
Complex Division<br />
Check for infinite denominator and set to unit vector if so&#8230;<br />
Complex Multiply<br />
Linear Interpolation with non phase accumulated values&#8230;</p>
<p>However, I&#8217;m a bit confused as to the inputs to each of these calculations&#8230; Either I&#8217;ve done something quite clever (to optimise it &#8211; and now I don&#8217;t remember what it is) or I&#8217;ve done something stupdi and it doesn&#8217;t work properly.</p>
<p>Let&#8217;s assume the former (optimistically). What I should be doing is :</p>
<p>taking the phase difference between the delayed frame and the one just before it (cartesian form)<br />
set  the magnitude of that of the delayed frame (the magnitude we want)<br />
divide by the magnitude of the previously output frame<br />
Now we have a vector which represents the phase and amp difference with the previously output frame<br />
Complex multiply this vector with the previously output frame<br />
[linearly interpolate]</p>
<p>I think I may have combined some of those steps to reduce the number of operations. To check this I&#8217;d have to do a little bit of algebra that I don&#8217;t have time for right now&#8230; If the above makes sense to you and you can figure out for yourself great &#8211; if not let me know &#8211; I&#8217;ll try and find a moment later&#8230;</p>
<p>Alex</p>
						]]>
					</description>

					
					
				</item>

					
		
	</channel>
	</rss>

