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;
}
Unless otherwise stated, the content of this page is licensed under GNU Free Documentation License.