|
View:
New views
15 Messages
—
Rating Filter:
Alert me
|
|
|
Cropping buffer - Server.sync + best wayHi all I need to crop a buffer. That's not straight forward in SC because of memory allocation on the buffer and such, so I'm wondering if the following is the best way to do this? Has anyone got a better method? But there are also some problems. See my comments. PS. I need the cropped buffer to have the same bufnum as the original buffer. cheers thor ( Routine.run { var cond; cond = Condition.new; // original buffer b = Buffer.read(s, "sounds/a11wlk01.wav"); "b.bufnum is: ".post; b.bufnum.postln; s.sync(cond); // temp buffer used in copying c = Buffer.alloc(s, 88864, b.numChannels); s.sync(cond); b.copyData(c, 0, 100000, 88864); // my cropping n = b.bufnum; // getting b's bufnum s.sync(cond); b.free; // cropped buffer with b's bufnum d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); s.sync(cond); c.copyData(d); s.sync(cond); c.free; \cropping_DONE.postln; }; ) d.play // is the new buffer there? yes d.bufnum // and it has the b.bufnum c.postln; c.play // c is freed. That's good. c.bufnum b.play // but I thought I'd freed b? b.bufnum // and now b and d share same bufnum !!! d.postln; b.postln; // and now I could do d.write(b...path) and I've changed the file forever (I'll not do that to your file) // I remember Julian telling me about s.bind once, but this doesn't work: // Should it not? ( s.bind({ b = Buffer.read(s, "sounds/a11wlk01.wav"); "b.bufnum is: ".post; b.bufnum.postln; s.sync; // temp buffer used in copying c = Buffer.alloc(s, 88864, b.numChannels); s.sync; b.copyData(c, 0, 100000, 88864); // my cropping n = b.bufnum; // getting b's bufnum s.sync; b.free; s.sync; // cropped buffer with b's bufnum d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); s.sync; c.copyData(d); s.sync; c.free; }) ) d.play |
|
|
Re: Cropping buffer - Server.sync + best wayTake a look at Buffer:free -- free { arg completionMessage; server.listSendMsg( this.freeMsg(completionMessage) ); } It instructs the server to release the buffer, but does nothing else. A Buffer (on the client) is really just a placeholder for the buffer number. Client-side Buffer objects don't know about changes in a server-side buffer's status. In your example, b was actually freed on the server, but "b" means (with respect to server communication), "Do stuff with whatever is being held at that buffer number right now." The other buffer object, d, puts new stuff at the same location that b is pointing to. b and d are distinct objects on the client, but they point to the same buffer number on the server. A sloppy C programmer can do something similar with a pointer variable that wasn't cleared properly -- i.e., try to access a memory location that is no longer allocated, or that is currently allocated for something else. There, the consequence is probably that the program crashes, rather than an unexpected response to .play. We could argue about whether Buffer:free should clear the bufnum variable. I'm skeptical because it might break code. If b's content is no longer meaningful in your code after freeing it, why not clear it? b = nil -- Cleaning up your garbage is a generally good programming practice anyway. hjh On Jul 20, 2008, at 9:14 AM, thor wrote:
: H. James Harkins : http://www.dewdrop-world.net .::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..: "Come said the Muse, Sing me a song no poet has yet chanted, Sing me the universal." -- Whitman |
|
|
Re: Cropping buffer - Server.sync + best wayLooks like JH has answered your main issue. Regarding s.bind, remember
what it does: it colllects together all the OSC messages that your function creates, and bundles them all off once the function has completed. So it's illogical to use s.sync inside an s.bind, because the OSC message sent out by s.sync won't be sent until the function has completed, yet s.sync won't let the function complete until it's heard a reply back... Dan 2008/7/20 thor <th.list@...>: > > Hi all > I need to crop a buffer. That's not straight forward in SC because of memory > allocation on the buffer and such, so I'm wondering if the following is the > best > way to do this? Has anyone got a better method? > But there are also some problems. See my comments. > PS. I need the cropped buffer to have the same bufnum as the original > buffer. > cheers > thor > > ( > Routine.run { > var cond; > cond = Condition.new; > > // original buffer > b = Buffer.read(s, "sounds/a11wlk01.wav"); > "b.bufnum is: ".post; b.bufnum.postln; > s.sync(cond); > // temp buffer used in copying > c = Buffer.alloc(s, 88864, b.numChannels); > s.sync(cond); > b.copyData(c, 0, 100000, 88864); // my cropping > n = b.bufnum; // getting b's bufnum > s.sync(cond); > b.free; > > // cropped buffer with b's bufnum > d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); > s.sync(cond); > c.copyData(d); > s.sync(cond); > c.free; > \cropping_DONE.postln; > }; > ) > > d.play // is the new buffer there? yes > d.bufnum // and it has the b.bufnum > c.postln; > c.play // c is freed. That's good. > c.bufnum > b.play // but I thought I'd freed b? > b.bufnum // and now b and d share same bufnum !!! > d.postln; > b.postln; > // and now I could do d.write(b...path) and I've changed the file forever > (I'll not do that to your file) > > > > // I remember Julian telling me about s.bind once, but this doesn't work: > // Should it not? > ( > s.bind({ > b = Buffer.read(s, "sounds/a11wlk01.wav"); > "b.bufnum is: ".post; b.bufnum.postln; > s.sync; > // temp buffer used in copying > c = Buffer.alloc(s, 88864, b.numChannels); > s.sync; > b.copyData(c, 0, 100000, 88864); // my cropping > n = b.bufnum; // getting b's bufnum > s.sync; > b.free; > s.sync; > > // cropped buffer with b's bufnum > d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); > s.sync; > c.copyData(d); > s.sync; > c.free; > }) > ) > d.play > -- http://www.mcld.co.uk _______________________________________________ sc-users mailing list info (subscribe and unsubscribe): http://swiki.hfbk-hamburg.de:8888/MusicTechnology/880 archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
|
|
Re: Cropping buffer - Server.sync + best wayWould you say that this is a good way of cropping a buffer though? Is there a better way? Also, I'm interested to know why the s.bind example is not working but perhaps Julian can explain that if he'll read this thread. cheers thor On 20 Jul 2008, at 15:10, James Harkins wrote:
|
|
|
Re: Cropping buffer - Server.sync + best way>Looks like JH has answered your main issue. Regarding s.bind, remember
>what it does: it colllects together all the OSC messages that your >function creates, and bundles them all off once the function has >completed. So it's illogical to use s.sync inside an s.bind, because >the OSC message sent out by s.sync won't be sent until the function >has completed, yet s.sync won't let the function complete until it's >heard a reply back... no, this is not correct. A sync inside a bind will separate the bundles and automatically send the second part when the first is received. So it should work, I don't know why it wouldn't. Take a look into the BundleNetAddr, maybe there is aome way to query your intermediate state. >Dan > > >2008/7/20 thor <th.list@...>: >> >> Hi all >> I need to crop a buffer. That's not straight forward in SC because of memory >> allocation on the buffer and such, so I'm wondering if the following is the >> best >> way to do this? Has anyone got a better method? >> But there are also some problems. See my comments. >> PS. I need the cropped buffer to have the same bufnum as the original >> buffer. >> cheers >> thor >> >> ( >> Routine.run { >> var cond; >> cond = Condition.new; >> >> // original buffer >> b = Buffer.read(s, "sounds/a11wlk01.wav"); >> "b.bufnum is: ".post; b.bufnum.postln; >> s.sync(cond); >> // temp buffer used in copying >> c = Buffer.alloc(s, 88864, b.numChannels); >> s.sync(cond); >> b.copyData(c, 0, 100000, 88864); // my cropping >> n = b.bufnum; // getting b's bufnum >> s.sync(cond); >> b.free; >> >> // cropped buffer with b's bufnum >> d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); >> s.sync(cond); >> c.copyData(d); >> s.sync(cond); >> c.free; >> \cropping_DONE.postln; >> }; >> ) >> >> d.play // is the new buffer there? yes >> d.bufnum // and it has the b.bufnum >> c.postln; >> c.play // c is freed. That's good. >> c.bufnum >> b.play // but I thought I'd freed b? >> b.bufnum // and now b and d share same bufnum !!! >> d.postln; >> b.postln; >> // and now I could do d.write(b...path) and I've changed the file forever >> (I'll not do that to your file) >> >> >> >> // I remember Julian telling me about s.bind once, but this doesn't work: >> // Should it not? >> ( >> s.bind({ >> b = Buffer.read(s, "sounds/a11wlk01.wav"); >> "b.bufnum is: ".post; b.bufnum.postln; >> s.sync; >> // temp buffer used in copying >> c = Buffer.alloc(s, 88864, b.numChannels); >> s.sync; >> b.copyData(c, 0, 100000, 88864); // my cropping >> n = b.bufnum; // getting b's bufnum >> s.sync; >> b.free; >> s.sync; >> >> // cropped buffer with b's bufnum >> d = Buffer.alloc(s, c.numFrames, c.numChannels, bufnum:n); >> s.sync; >> c.copyData(d); >> s.sync; >> c.free; >> }) >> ) >> d.play >> > > > >-- >http://www.mcld.co.uk > >_______________________________________________ >sc-users mailing list > >info (subscribe and unsubscribe): >http://swiki.hfbk-hamburg.de:8888/MusicTechnology/880 >archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ >search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ -- . _______________________________________________ sc-users mailing list info (subscribe and unsubscribe): http://swiki.hfbk-hamburg.de:8888/MusicTechnology/880 archive: http://www.listarc.bham.ac.uk/marchives/sc-users/ search: http://www.listarc.bham.ac.uk/lists/sc-users/search/ |
|
|
Re: Cropping buffer - Server.sync + best waybut I've implemented the crop method like this: (still interested in improvements : ) b = Buffer.read(s, "sounds/a11wlk01.wav"); b.play b.crop(100000, 66666, false) b.play b + Buffer { crop {arg startFrame, numFrames, overwrite=false; var s, cond, tempbuf, tempbufnum, newbuf, chNum; cond = Condition.new; s = Server.default; Routine.run { chNum = this.numChannels; s.sync(cond); tempbuf = Buffer.alloc(s, numFrames, chNum); s.sync(cond); this.copyData(tempbuf, 0, startFrame, numFrames); tempbufnum = this.bufnum; s.sync(cond); this.free; s.sync(cond); newbuf = Buffer.alloc(s, tempbuf.numFrames, tempbuf.numChannels, bufnum:tempbufnum); s.sync(cond); tempbuf.copyData(newbuf); s.sync(cond); tempbuf.free; tempbuf = nil; if(overwrite, { newbuf.write(this.path, "aiff", "int16") }); s.sync(cond); this.updateInfo; // update so the buffer object has the new buffer info }; } } On 20 Jul 2008, at 16:54, Julian Rohrhuber wrote:
|
|
|
Re: Cropping buffer - Server.sync + best way...Just to tag on to this I have a quick query relating to copying buffer data.
Should Buffer.copyData not wrap when the end of the source buffer is reached? I'd imagine one fairly common usage of .copyData is to grab stuff out of a circling buffer into smaller buffers on the fly? It's straightforward to just composite around the end of the source buffer but not altogether that pretty. Below is how I've done it but is there a more elegant way? ( var source,dest,start,size,firstHalf,secondHalf; fork{ source = Buffer.read(s,"sounds/a11wlk01.wav"); s.sync; dest = Buffer.alloc(s,source.sampleRate*2,source.numChannels); start = source.numFrames * 0.95; size = dest.numFrames; if((start+size) > source.numFrames,{ firstHalf = start - source.numFrames; secondHalf = size - firstHalf; source.copyData(dest,0,start,firstHalf); source.copyData(dest,firstHalf,0,secondHalf); s.sync; dest.play; },{ source.copyData(dest,0,start,size); s.sync; dest.play; }); } ) best, piaras |
|
|
Re: Cropping buffer - Server.sync + best waysome minor suggestions...
i would avoid Server.default inside a method. specially here since the Buffer object already knows which server it belongs to. and this.numChannels and this.bufnum could be just numChannels and bufnum. your argument numFrames you might want to rename just to make it different from Buffer.numFrames. the first .sync should not be needed. and perhaps add an action function? _f /* b = Buffer.read(s, "sounds/a11wlk01.wav"); b.play b.crop(100000, 66666, false) b.play b */ + Buffer { crop {arg startFrame, frames, overwrite=false, action; var cond, tempbuf, newbuf; cond = Condition.new; Routine.run { tempbuf = Buffer.alloc(server, frames, numChannels); server.sync(cond); this.copyData(tempbuf, 0, startFrame, frames); server.sync(cond); this.free; server.sync(cond); newbuf = Buffer.alloc(server, tempbuf.numFrames, tempbuf.numChannels, bufnum:bufnum); server.sync(cond); tempbuf.copyData(newbuf); server.sync(cond); tempbuf.free; tempbuf = nil; if(overwrite, { newbuf.write(this.path, "aiff", "int16") }); server.sync(cond); this.updateInfo(action); // update so the buffer object has the new buffer info }; } } 21 jul 2008 kl. 01.04 skrev thor: > > Thanks for all the replies. Right now I don't have time to > investigate the bind issue > but I've implemented the crop method like this: > > (still interested in improvements : ) > > > b = Buffer.read(s, "sounds/a11wlk01.wav"); > b.play > b.crop(100000, 66666, false) > b.play > b > > > + Buffer { > crop {arg startFrame, numFrames, overwrite=false; > var s, cond, tempbuf, tempbufnum, newbuf, chNum; > cond = Condition.new; > s = Server.default; > > Routine.run { > chNum = this.numChannels; > s.sync(cond); > tempbuf = Buffer.alloc(s, numFrames, chNum); > s.sync(cond); > this.copyData(tempbuf, 0, startFrame, numFrames); > tempbufnum = this.bufnum; > s.sync(cond); > this.free; > s.sync(cond); > > newbuf = Buffer.alloc(s, tempbuf.numFrames, tempbuf.numChannels, > bufnum:tempbufnum); > s.sync(cond); > tempbuf.copyData(newbuf); > s.sync(cond); > tempbuf.free; > tempbuf = nil; > > if(ove |