[Cs-dev] string array assignment and loops
Date | 2014-03-21 13:20 |
From | Victor Lazzarini |
Subject | [Cs-dev] string array assignment and loops |
Following Rory’s recent report, this is what I found out. In the following code until initCount == 4 do Schannel sprintfk "channel%d\n", initCount+1 gSChannels[initCount] strcpy Schannel initCount = initCount+1 od the loop body seems to be translated into something like this Schannel sprintfk "channel%d\n", initCount+1 #S1 strcpy Schannel gSChannels[initCount] ##array_set.i2 #S1 initCount = initCount+1 which is standard. Now the problem is that array set uses the following code to copy the data memcpy(mem, p->value, dat->arrayMemberSize); which copies the STRINGDAT #S1, which will be the same for all array members, and contain the last string copied by strcpy. So all members are going to be pointing to the same memory, and that will contain the last string copied. For this to work, we would need a specialised array_set() for strings that copies the string rather than the STRINGDAT pointer. Note that this should also be a problem for PVSDAT arrays, where the same thing can happen. ======================== Dr Victor Lazzarini Senior Lecturer NUI Maynooth, Ireland victor dot lazzarini at nuim dot ie ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech _______________________________________________ Csound-devel mailing list Csound-devel@lists.sourceforge.net |
Date | 2014-03-21 14:09 |
From | Steven Yi |
Subject | Re: [Cs-dev] string array assignment and loops |
That sounds like what I was thinking. I don't think we should do a specialized array_set though, as that goes against the generality of the type system. My take is to add the copy function to the CS_TYPE, then use that as a means to copy values. So the change would be to replace memcpy with something like: dat->subtype->copyByValue(mem, p->value); Adding a copyByValue function to the types will allow this to be generalized for strings, pvs, etc. It should also be done then when copying values for UDO's. The standard function would probably just wrap memcpy. I can take a stab at this as I was just recently working in the type code. On Fri, Mar 21, 2014 at 9:20 AM, Victor Lazzarini |
Date | 2014-03-21 14:16 |
From | Victor Lazzarini |
Subject | Re: [Cs-dev] string array assignment and loops |
Sounds like the correct solution. ======================== Dr Victor Lazzarini Senior Lecturer NUI Maynooth, Ireland victor dot lazzarini at nuim dot ie On 21 Mar 2014, at 14:09, Steven Yi |
Date | 2014-03-21 14:22 |
From | Steven Yi |
Subject | Re: [Cs-dev] string array assignment and loops |
Okay, sounds like it's worth taking a shot then. I'll give it a go and report back here once I get an implementation going. Thanks! steven On Fri, Mar 21, 2014 at 10:16 AM, Victor Lazzarini |
Date | 2014-03-21 23:43 |
From | Steven Yi |
Subject | Re: [Cs-dev] string array assignment and loops |
Took a while to sort out, but I think I've got it working. I've pushed the changes to SF. The changes essentially just redirect to use a copyValue function pointer for setting/getting values in arrays, as well as part of the UDO (xin, xout, and perf-time) args copying. The variable copy functions were added to Engine/csound_standard_types.c. I wasn't quite sure what needs to be copied for w-sigs and f-sigs. Right now they're just using memcpy which is not correct (but is what is used prior to this change). Also, the array copying code I put in is heavy-handed, allocating memory each call. I think it needs to be rewritten to not allocate if there is enough memory already available. Also, from a quick look it looks like it may need to free the previous data pointer. (oops!) John and Victor: Could you review those copy functions in csound_standard_types.c? Otherwise, with Rory's example, if I change what index is used to access the array I am getting different values. Also, make csdtests is passing, and a couple example CSD's I tried seemed to be working alright. Thanks! steven On Fri, Mar 21, 2014 at 10:22 AM, Steven Yi |
Date | 2014-03-21 23:52 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Attachments | None None |
Nice one Steven. I'm going to try out some things and let you know how I get on! On 21 March 2014 23:43, Steven Yi <stevenyi@gmail.com> wrote: Took a while to sort out, but I think I've got it working. I've pushed |
Date | 2014-03-22 00:33 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Attachments | None None |
Looks to be much better Steven. Tanks for this. Ah to my next question. Perhaps it's a little late and I'm missing something here, but I can't see why the instr2 below prints out change messages every k-cycle when the channels are only being changed once every 10 seconds? Thanks for your work on this. I'm starting to get stringy with it :) gSChannels[] init 4 instr 1 initCount init 0 ;initliase channel and value arrays on init-pass until initCount == 4 do Schannel sprintf "channel%d", initCount+1 gSChannels[initCount] strcpy Schannel chnset "empty", gSChannels[initCount] prints gSChannels[initCount] initCount = initCount+1 enduntil ;randomly change values and update channels k1 metro 1 kIndex randh 3, kr, 2 kNewVal rand 100, sr, 2 if(k1==.1) then Svalue sprintfk "%d", kNewVal chnset Svalue, gSChannels[abs(kIndex)] endif endin instr 2 ;now check for changes to any of the channels kIndex = 0 Svalue[] init 4 kChanged[] init 4 loop1: Svalue[kIndex] chnget gSChannels[kIndex] kChanged[kIndex] changed Svalue[kIndex] if(kChanged[kIndex]==1) then; SprintMsg sprintfk "INSTR2 - %s changed, new value: %s\n", gSChannels[kIndex], Svalue[kIndex] printks SprintMsg, .1 endif kIndex = kIndex+1 if kIndex < 3 kgoto loop1 endin On 21 March 2014 23:52, Rory Walsh <rorywalsh@ear.ie> wrote:
|
Date | 2014-03-22 08:59 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Attachments | None None |
Whoops, it was late when I posted that. I was testing a metro value to be .1! This code should illustrate the point better. In my understanding of things instr2 should only print to screen when a channel value has changed? Here's another variation only this time I'm firing instrument 2 from instrument one. Makes no difference:gSChannels[] init 4 instr 1 initCount init 0 ;initliase channel and value arrays on init-pass until initCount == 4 do Schannel sprintf "channel%d", initCount+1 gSChannels[initCount] strcpy Schannel chnset "empty", gSChannels[initCount] prints gSChannels[initCount] initCount = initCount+1 enduntil ;randomly change values and update channels k1 metro 1 kIndex randh 3, kr, 2 kNewVal rand 100, sr, 2 if(k1==1) then Svalue sprintfk "%d", kNewVal chnset Svalue, gSChannels[abs(kIndex)] ;printks Svalue, .1 endif endin instr 2 ;now check for changes to any of the channels k1 metro 1 if k1== 1 then kIndex = 0 Svalue[] init 4 loop1: Svalue[kIndex] chnget gSChannels[kIndex] kChanged changed Svalue[kIndex] if(kChanged==1) then; SprintMsg sprintfk "INSTR2 - %s changed, new value: %s\n", gSChannels[kIndex], Svalue[kIndex] printks SprintMsg, .1 endif kIndex = kIndex+1 if kIndex < 4 kgoto loop1 endif endin gSChannels[] init 4 instr 1 initCount init 0 ;initliase channel and value arrays on init-pass until initCount == 4 do Schannel sprintf "channel%d", initCount+1 gSChannels[initCount] strcpy Schannel chnset "empty", gSChannels[initCount] prints gSChannels[initCount] initCount = initCount+1 enduntil ;randomly change values and update channels k1 metro 1 kIndex randh 3, kr, 2 kNewVal rand 100, sr, 2 if(k1==1) then Svalue sprintfk "%d", kNewVal chnset Svalue, gSChannels[abs(kIndex)] event "i", 2, 0, ksmps/sr endif endin instr 2 ;now check for changes to any of the channels setksmps 1 k1 metro 1 if k1== 1 then kIndex = 0 Svalue[] init 4 loop1: Svalue[kIndex] chnget gSChannels[kIndex] kChanged changed Svalue[kIndex] if(kChanged==1) then; SprintMsg sprintfk "INSTR2 - %s changed, new value: %s\n", gSChannels[kIndex], Svalue[kIndex] printks SprintMsg, .1 endif kIndex = kIndex+1 if kIndex < 3 kgoto loop1 endif endin On 22 March 2014 00:33, Rory Walsh <rorywalsh@ear.ie> wrote:
|
Date | 2014-03-24 19:11 |
From | Steven Yi |
Subject | Re: [Cs-dev] string array assignment and loops |
Attachments | test.csd None None |
Hi Rory, I looked at this a bit and I'm not sure what's going on. I've attached a CSD with some modifications (fixes up index generation, modified printout messages). If you run it, you'll see that the index is always 0 for what channel index has changed, though the contents might show from a different channel. I get messages like: INSTR2 0 - channel4 changed, new value: 2: -43 INSTR2 0 - channel4 changed, new value: 3: -7 INSTR2 0 - channel4 changed, new value: 2: 100 INSTR2 0 - channel4 changed, new value: 1: 19 INSTR2 0 - channel4 changed, new value: 0: -99 I think there's a fundamental issue with trying to use changed with an array of Strings. What happens is that the s[kIndex] generates out to a temp var, something like: #S6 array_get Svalue index kChanged changed #S6 but from what I understand, it means that #S6 is going to be changing every iteration of that loop as you're constantly resetting what is in #S6 from the array. Now, what I don't understand yet is why the indexes don't quite match between the messages. On the other hand, I'd highly recommend rolling your own changed code, storing a copying of the array locally and comparing/resetting against that. On Sat, Mar 22, 2014 at 4:59 AM, Rory Walsh |
Date | 2014-03-24 19:14 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Thanks for taking a look Steven. I did once write a UDO for this but abandoned it with glee when I saw a string version of changed. I'll go back to it for now. Thanks for the feedback. On 24 March 2014 19:11, Steven Yi |
Date | 2014-03-24 20:21 |
From | Victor Lazzarini |
Subject | Re: [Cs-dev] string array assignment and loops |
There is also strcmp that can be used for string checks. On 24 Mar 2014, at 19:14, Rory Walsh wrote: > Thanks for taking a look Steven. I did once write a UDO for this but > abandoned it with glee when I saw a string version of changed. I'll go > back to it for now. Thanks for the feedback. > > On 24 March 2014 19:11, Steven Yi |
Date | 2014-03-28 16:30 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Attachments | test.csd None None |
I'm still having difficulties here with comparing values in a string array. Attached is a csd I'm using. I'm writing values to a string array AND a channel. I then try to change the channel value, and check against the value in the array to see if it has changed, but I get a segfault. Here's the backtrace. Program received signal SIGABRT, Aborted. 0x00007ffff730c425 in __GI_raise (sig= |
Date | 2014-03-28 17:34 |
From | Victor Lazzarini |
Subject | Re: [Cs-dev] string array assignment and loops |
I spotted a bug in the code, which I fixed in git develop (github!). See if it works now. ======================== Dr Victor Lazzarini Senior Lecturer NUI Maynooth, Ireland victor dot lazzarini at nuim dot ie On 28 Mar 2014, at 16:30, Rory Walsh |
Date | 2014-03-28 17:47 |
From | Rory Walsh |
Subject | Re: [Cs-dev] string array assignment and loops |
Bingo. Works a treat now. Have you guys discussed when the next release will happen? I think there has been quite a few bugs fixed since the last rc? On 28 March 2014 17:34, Victor Lazzarini |
Date | 2014-03-28 18:57 |
From | Victor Lazzarini |
Subject | Re: [Cs-dev] string array assignment and loops |
yes, at easter. ======================== Dr Victor Lazzarini Senior Lecturer NUI Maynooth, Ireland victor dot lazzarini at nuim dot ie On 28 Mar 2014, at 17:47, Rory Walsh |