basic function
basic function to get http-output and let the contained text get 'spoken' to a buffer
This function must go into a file named read_n_record.rtf and has to be in the same folder as the function-call (no sub-directory)
/* old */ /* © Stefan Nussbaumer 2007, with portions from others ... You may use, remix this for any purpose under the condition that the result is being passed on (published) under the same conditions (see license) as this originating piece of code. If any part of this is being published in a compiled program, the regarding parts have to be published as code together with the compiled program. The code must be available for free (at no expenses). If you alter this code you may add your name to the list of authors (copyright-holders). Please leave the names of authors having contributed before you untouched. published under the terms of this Creative-Commons-license: http://creativecommons.org/licenses/by-sa/2.0/at/deed.en */ // function with the username as only parameter - declared as part of the default environment (like a global variable) // who = username (ebay), user-id (mercadolibre), loops = number of comments to read resp. sampled ~readNrecord = { |who, loops| var string, removeTags, tags, regexp, newstring, last, ebayString, date, init, start, end, duration, doer, count, usertemp, voice, dur; ~userSign = List(); who.do({ |i| i.postln; ~userSign.add(i.ascii+50) }); ~userSign.postln; ~ratings = List(); ~u_fbs = List(); // SC utilizes Apple's built-in speech-synthesis. Thus this can't be captured directly, requiring Jack -> get it at http://jackosx.com/ // the number of possible voice-channels (no audio-channels!) isn't 128 as stated in the help-files - only 16! Calling speech twice at the same time on the same voice-channel will crash SC inevitably ... // there have been some fixes to Speech recently, that should prevent SC from crashing. Unfortunately these fixes also broke my code :( if(Speech.initialized.not, {Speech.init(16)}); // Pipe utilizing 'Curl' to get website-output to SC p = Pipe.new("curl \"http://hforum.pytalhost.com/get.php?user="++who++"&scout=1&submit=get+data\"", "r"); // write the output to a string. close the pipe when done string = String.new; l = p.getLine; string = l; while({l.notNil}, {l = p.getLine; if(l.notNil, {string = string ++ l})}); p.close; //string.postln; // get rid of JavaScript junk // lent from http://www.create.ucsb.edu/pipermail/sc-users/2005-March/017206.html removeTags = { arg html, tagname; var pos; var endpos; var headPart; var tailPart; pos = html.find("<" ++ tagname); if ( pos != nil, { headPart = html.copyFromStart(pos - 1); html = html.copyToEnd(pos); endpos = html.find(">"); if (endpos != nil, { // should always be !=nil, otherwise something's wrong html = html.copyToEnd(endpos + 1); // now remove end tag pos = html.find("</" ++ tagname ++ ">"); if ( pos!=nil, { headPart = headPart + html.copyFromStart(pos-1); html = html.copyToEnd(pos + tagname.size + 3); }); }); html = headPart + html; html = removeTags.value(html, tagname); // recursion to handle next occurrence }); html; }; tags = ["script"]; newstring = string; tags.size.do({|i| newstring = removeTags.value(newstring, tags[i]) }); /* read output into a file if desired */ //f = File("/Users/stefannussbaumer/Music/SuperCollider/ebay_generator/ebay.html", "w"); //f.write(newstring); //f.close; //Document.open("/Users/stefannussbaumer/Music/SuperCollider/ebay_generator/ebay.html"); //b = File("/Users/stefannussbaumer/Music/SuperCollider/ebay_generator/ebay.html", "r"); // for offline-use only //newstring = b.readAllString; // eval the string into the auto-global 'a' (small letters are autoglobal, though they relate to certain functionalities like 's' by default stands for the server a = newstring.interpret; /* ebay-generator only */ // apple-speech voices (preselection - some are not useful) // ~voice = [1,6,7,11,14,15,17,18,19,20,21]; // get comments by random ~doers = Array.fill(loops, { a['feedbacks'].size.xrand } ).postln; // just to easily see what get's posted Document.allDocuments[0].string_(""); Document.allDocuments[0].front; // 'speak' the comments in a timed loop to the 20 consequtive buffers // unfortunately this can't happen all at the same time, as each voice goes to all possible inputs ~elapsed = Array(loops); // empty array (number of slots = loops) for elapsed times from beginning of Speech-process to the end of each spoken comment Speech.doneAction_({ end = Main.elapsedTime; ~record.free; // free the recording synth after each spoken comment - proved to more reliable than just setting a new buffer-index if(count.isNil, {count = 1},{count = count+1}); Speech.stop(voice, voice); // strange - though this is the "doneAction" Speech has to be freed explicitely - used to work without before recent changes to the Speech-object voice = [0,10].choose; // mercadolibre only - there are only two spanish voices (Martha e Miguel) Speech.setSpeechVoice(voice, voice); if(voice == 10, { Speech.setSpeechRate(voice, 150); }, { Speech.setSpeechRate(voice, 120); }); if(count < loops, { ~record = Synth(\sampleIn1, [\out, 2, \bufnum, ~buffer[count].bufnum]); // initialise a new instance of the recording synth for each comment, recording each comment to a predestined buffer a['feedbacks'][~doers[count]]['comment'].asString.speak([0,10].choose); if(a['feedbacks'][~doers[count]]['feedback'] == 'pos', { ~ratings.add(1) }); if(a['feedbacks'][~doers[count]]['feedback'] == 'neu', { ~ratings.add(0) }); if(a['feedbacks'][~doers[count]]['feedback'] == 'neg', { ~ratings.add(-1) }); ~u_fbs.add(a['feedbacks'][~doers[count]]['user_feedbacks'].asInteger); dur = end-start; ~elapsed.add(dur); // store duration from beginning of the process to the end of reading (always counting from zero - not the beginning of the current reading!!!) }, { // ~record.free; dur = end-start; ~elapsed.add(dur); ~durations = Array(~elapsed.size); ~durations.add(~elapsed[0]); ~elapsed.do({ |i, j| var temp; ~elapsed[j+1].notNil.if{temp = (i-~elapsed[j+1]).abs; // substract ~elapsed[i] from ~elapsed[i+1] to get the exact time of a reading ~durations.add(temp)}}); // write each duration to an environment variable ~durations.postln; ~step1 = true; // preprocessing finished - you may go on to play your song }); }); start = Main.elapsedTime; ~record = Synth(\sampleIn1, [\out, 2, \bufnum, ~buffer[0].bufnum]); Speech.setSpeechVoice(voice, voice); a['feedbacks'][~doers[0]]['comment'].asString.speak([0,10].choose.postln); if(a['feedbacks'][~doers[0]]['feedback'] == 'pos', { ~ratings.add(1) }); if(a['feedbacks'][~doers[0]]['feedback'] == 'neu', { ~ratings.add(0) }); if(a['feedbacks'][~doers[0]]['feedback'] == 'neg', { ~ratings.add(-1) }); ~u_fbs.add(a['feedbacks'][~doers[0]]['user_feedbacks'].asInteger); /* older version takes longer than the method above, more accurate ... */ //t = Task({ // ~doers.do({|i, j| //// var startTime, endTime, duration; // var count; // if(j>15 and:{j.mod(16) == 0}, {fact = fact+1}); // if(j>15, {count = j-(16*fact)}, {count = j}); //// if(j.mod(16) == 15, {fact = fact+1}); //// if(j>15, {count = j-(16*fact)}, {count = j}); // 15.wait; // Speech.setSpeechVoice(count, ~voice.choose.postln); //// ~buffer[j].free; // startTime = Main.elapsedTime; //// "ich bin ein Kommentar".speak(j); // if(~record.isPlaying, { ~record.isPlaying.postln; ~record.set(\bufnum, ~buffer[j].bufnum) },{~record = Synth(\sampleIn, [\out, 2, \bufnum, ~buffer[j].bufnum])}); // a['feedbacks'][i]['comment'].asString.speak(count); // a['feedbacks'][i]['feedback'].postln; // if(a['feedbacks'][i]['feedback'] == 'pos', { ~ratings.add(1) }); // if(a['feedbacks'][i]['feedback'] == 'neu', { ~ratings.add(0) }); // if(a['feedbacks'][i]['feedback'] == 'neg', { ~ratings.add(-1) }); // ~u_fbs.add(a['feedbacks'][i]['user_feedbacks'].asInteger); // ("startTime was:"+startTime).postln; // j.postln; // count.postln; // fact.postln; //// this.streamHasEnded.if{"step 1 done".postln}; // }); //}).play; }
page revision: 26, last edited: 31 Aug 2009 01:54