Re: for and ^ question
On Fri, Jan 01, 2021 at 05:41:04PM -0800, ToddAndMargo via perl6-users wrote: > On 1/1/21 6:32 AM, David Santiago wrote: > > say $_ for {0.1+$_}...^5 > > Is there a way to do this without the finger wagging? > > say $_ for {0.1+$_}...^2 If you're going to a sequence operator ("...") instead of a range operator (".."), then you can specify the increment this way and it may be more readable: > say $_ for 0.1, 0.2 ...^ 2; Raku will auto-deduce the sequence from the values in the list on the LHS of the sequence operator: > say $_ for 0.6, 1.1 ...^ 10; This can be of course extended -- to count from $a up to $b in steps of $x, one can write: > say $_ for $a, $a+$x ...^ $b Note that in these examples the caret is part of the sequence operator, it's not a prefix to the $b argument. Pm
Re: for and ^ question
On 1/1/21 6:32 AM, David Santiago wrote: say $_ for {0.1+$_}...^5 Hi David, Thank you! Is there a way to do this without the finger wagging? say $_ for {0.1+$_}...^2 Use of uninitialized value of type Any in numeric context in block at line 1 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 > for {0.1+$_}...^2 {print "$_\n";} Use of uninitialized value of type Any in numeric context in block at line 1 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 And what is going wrong here? for {0.3+$_}...^2 {print "$_\n";} ... 41076 41076.3 41076.6 41076.9 41077.2 41077.5 41077.8 41078.1 41078.4 41078.7 41079 41079.3 41079.6 41079.9 41080.2 41080.5 41080.8 41081.1 41081.4 41081.7 ... Many thanks, -T
Re: concurrency of asynchronous events - input from multiple keyboards
I think the simplest way to turn that into a Supply is to use the `supply` keyword my $pm = Audio::PortMIDI.new; my $input = supply { my $stream = $pm.open-input($input-device-number, 32); DONE { $stream.close; } loop { emit $stream.read(1); } } react { whenever key-pressed(:!echo) { given .fc { when 'q' { done } default { .raku.say } } } my $voice = $pm.open-output($output-device-number, 32); whenever $input { $voice.write(|$_); } } On Fri, Jan 1, 2021 at 12:31 PM Nathan Gray wrote: > I am working on a small virtual organ program, where I have > multiple MIDI controller keyboards which can be connected to one > or more synthesizer channels to emit various sounds > simultaneously. > > At this point, I am able to read events from a single MIDI > controller and send the events to the correct synthesizer channel > (I'm using Timidity at the moment). > > I would like to read keypresses from the computer keyboard and > use those to adjust which synthesizers receive which MIDI events. > In other words, I press a note on my MIDI controller and the note > plays a sound on the synthesizer I have set up. When I press the > letter 'a' on my computer keyboard, I would like to add another > synthesizer, so that subsequent notes played on the MIDI > controller send events to the original synthesizer and to a new > synthesizer. > > I was able to build a script to read in events from the computer > keyboard (via the module Term::ReadKey). I read these keypresses > in a react block with a whenever: > > react { > whenever key-pressed(:!echo) { > # Eventually will connect or disconnect a synthesizer for the > relevant MIDI controller. > # Currently just prints out the key that was pressed. > given .fc { > when 'q' { done } > default { .raku.say } > } > } > } > > The MIDI events are being read via the module Audio::PortMIDI in > a loop block: > > my $pm = Audio::PortMIDI.new; > my $stream = $pm.open-input($input-device-number, 32); > my $voice = $pm.open-output($output-device-number, 32); > # Read events from the MIDI controller and write to the synthesizer. > loop { > if $stream.poll { > my @notes = $stream.read(1); > $voice.write(@notes); > } > } > > I'm struggling to figure out how to combine the react block for > the computer keyboard events and the loop block for the MIDI > events. I would like to be able to accept events from both > devices concurrently. > > It seems like I might need to turn the loop into a Supply of some > kind, but I'm not sure how I would go about doing that. If I > understand correctly, once it is a supply, I could add it to the > react block as another whenever event. > > I have found examples of how to create a Supply using a loop and > a Promise that is kept after a specific amount of time > ( > https://stackoverflow.com/questions/57486372/concurrency-react-ing-to-more-than-one-supply-at-a-time > ), > but I have not found anything that is polling from a data stream. > > My attempt of polling the stream in a whenever block errors out, > without me ever pressing a key, which makes it seem like it is > trying to read when there are no keypress events available. > > whenever so $stream.poll { > my @notes = $stream.read(1); > ... > } > > Type check failed for return value; expected Str but got Any (Any) > in sub with-termios at > /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A > (Term::ReadKey) line 20 > in block at > /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A > (Term::ReadKey) line 51 > > Any insights would be greatly appreciated. > > -kolibrie >
Re: concurrency of asynchronous events - input from multiple keyboards
As it seems that Audio::PortMIDI lacks non-blocking interface, I think a solution would be to read events in a dedicated thread and re-submit them into a Supplier. Something like: my Supplier $midi-events; start { loop { my $ev = $midi.read; $midi-events.emit: $ev; } } $midi-events can then be used in your react block. BTW, I think calling method 'poll' must not be needed because `read` should block until actual event is available. At least this is how I understand the normal order of things. Best regards, Vadim Belman > On Jan 1, 2021, at 1:23 PM, Nathan Gray wrote: > > I am working on a small virtual organ program, where I have > multiple MIDI controller keyboards which can be connected to one > or more synthesizer channels to emit various sounds > simultaneously. > > At this point, I am able to read events from a single MIDI > controller and send the events to the correct synthesizer channel > (I'm using Timidity at the moment). > > I would like to read keypresses from the computer keyboard and > use those to adjust which synthesizers receive which MIDI events. > In other words, I press a note on my MIDI controller and the note > plays a sound on the synthesizer I have set up. When I press the > letter 'a' on my computer keyboard, I would like to add another > synthesizer, so that subsequent notes played on the MIDI > controller send events to the original synthesizer and to a new > synthesizer. > > I was able to build a script to read in events from the computer > keyboard (via the module Term::ReadKey). I read these keypresses > in a react block with a whenever: > >react { >whenever key-pressed(:!echo) { ># Eventually will connect or disconnect a synthesizer for the > relevant MIDI controller. ># Currently just prints out the key that was pressed. >given .fc { >when 'q' { done } >default { .raku.say } >} >} >} > > The MIDI events are being read via the module Audio::PortMIDI in > a loop block: > >my $pm = Audio::PortMIDI.new; >my $stream = $pm.open-input($input-device-number, 32); >my $voice = $pm.open-output($output-device-number, 32); ># Read events from the MIDI controller and write to the synthesizer. >loop { >if $stream.poll { >my @notes = $stream.read(1); >$voice.write(@notes); >} >} > > I'm struggling to figure out how to combine the react block for > the computer keyboard events and the loop block for the MIDI > events. I would like to be able to accept events from both > devices concurrently. > > It seems like I might need to turn the loop into a Supply of some > kind, but I'm not sure how I would go about doing that. If I > understand correctly, once it is a supply, I could add it to the > react block as another whenever event. > > I have found examples of how to create a Supply using a loop and > a Promise that is kept after a specific amount of time > (https://stackoverflow.com/questions/57486372/concurrency-react-ing-to-more-than-one-supply-at-a-time), > but I have not found anything that is polling from a data stream. > > My attempt of polling the stream in a whenever block errors out, > without me ever pressing a key, which makes it seem like it is > trying to read when there are no keypress events available. > >whenever so $stream.poll { >my @notes = $stream.read(1); >... >} > > Type check failed for return value; expected Str but got Any (Any) > in sub with-termios at > /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A > (Term::ReadKey) line 20 > in block at > /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A > (Term::ReadKey) line 51 > > Any insights would be greatly appreciated. > > -kolibrie signature.asc Description: Message signed with OpenPGP
concurrency of asynchronous events - input from multiple keyboards
I am working on a small virtual organ program, where I have multiple MIDI controller keyboards which can be connected to one or more synthesizer channels to emit various sounds simultaneously. At this point, I am able to read events from a single MIDI controller and send the events to the correct synthesizer channel (I'm using Timidity at the moment). I would like to read keypresses from the computer keyboard and use those to adjust which synthesizers receive which MIDI events. In other words, I press a note on my MIDI controller and the note plays a sound on the synthesizer I have set up. When I press the letter 'a' on my computer keyboard, I would like to add another synthesizer, so that subsequent notes played on the MIDI controller send events to the original synthesizer and to a new synthesizer. I was able to build a script to read in events from the computer keyboard (via the module Term::ReadKey). I read these keypresses in a react block with a whenever: react { whenever key-pressed(:!echo) { # Eventually will connect or disconnect a synthesizer for the relevant MIDI controller. # Currently just prints out the key that was pressed. given .fc { when 'q' { done } default { .raku.say } } } } The MIDI events are being read via the module Audio::PortMIDI in a loop block: my $pm = Audio::PortMIDI.new; my $stream = $pm.open-input($input-device-number, 32); my $voice = $pm.open-output($output-device-number, 32); # Read events from the MIDI controller and write to the synthesizer. loop { if $stream.poll { my @notes = $stream.read(1); $voice.write(@notes); } } I'm struggling to figure out how to combine the react block for the computer keyboard events and the loop block for the MIDI events. I would like to be able to accept events from both devices concurrently. It seems like I might need to turn the loop into a Supply of some kind, but I'm not sure how I would go about doing that. If I understand correctly, once it is a supply, I could add it to the react block as another whenever event. I have found examples of how to create a Supply using a loop and a Promise that is kept after a specific amount of time (https://stackoverflow.com/questions/57486372/concurrency-react-ing-to-more-than-one-supply-at-a-time), but I have not found anything that is polling from a data stream. My attempt of polling the stream in a whenever block errors out, without me ever pressing a key, which makes it seem like it is trying to read when there are no keypress events available. whenever so $stream.poll { my @notes = $stream.read(1); ... } Type check failed for return value; expected Str but got Any (Any) in sub with-termios at /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A (Term::ReadKey) line 20 in block at /home/kolibrie/.raku/sources/C758559420AEADF99B8D412BDFADA739CAC14C2A (Term::ReadKey) line 51 Any insights would be greatly appreciated. -kolibrie signature.asc Description: PGP signature
Re: for and ^ question
> for .1^...5 {print "$_\n";} 1.1 2.1 3.1 4.1 both still increments by 1 What am I doing wrong? do this if you want to increment by 0.1: say $_ for {0.1+$_}...^5 Best regards, David Santiago
Re: for and ^ question
On 1/1/21 3:23 AM, Kevin Pye wrote: ..^ is an operator. You can't put spaces in the middle of an operator. > for ^2.1..4.5 {print "$_\n";} Range objects are not valid endpoints for Ranges in block at line 1 > for 2.1^..4.5 {print "$_\n";} 3.1 4.1 > for .1^...5 {print "$_\n";} 1.1 2.1 3.1 4.1 both still increments by 1 What am I doing wrong?
Re: for and ^ question
..^ is an operator. You can't put spaces in the middle of an operator. On Fri, 1 Jan 2021 at 22:13, ToddAndMargo via perl6-users < perl6-users@perl.org> wrote: > >> On Fri, 1 Jan 2021 at 18:59, ToddAndMargo via perl6-users > >> mailto:perl6-users@perl.org>> wrote: > >> > >> >> ^ note: ^3 means the integer "just before" 3 (zero is > >> presume to be the > >> >> start point) > >> >> > >> >>3^ means the integer "just after" 3 (an ending > >> point is > >> >> required) > >> >> > >> >> > >> > >> On 12/31/20 10:15 PM, Kevin Pye wrote: > >> > No, it does not. Go back and read what Brad wrote; he was quite > >> explicit. > >> > > >> > Nothing about the range 0 ..^ 3 (for which "^3" is just a > short-cut) > >> > says anything about integers. It is the range of numbers (real > >> numbers > >> > if you like) ranging from 0 to 3, but excluding 3. In standard > >> > mathematical notation that would be "[0,3)". If you iterate over > the > >> > range then you start with the beginning of the range and keep > >> adding one > >> > until you reach the end (in this case ignoring the final value if > >> it is > >> > equal to the end-point). > >> > > >> > If the range were 0.5 .. 3 then the iterated values would be 0.5, > >> 1.5 > >> > and 2.5. > >> > >> > >> Hi Kevin, > >> > >> My notes were for "for" loops. > >> > >> > for ^2 {print "$_\n";} > >> 0 > >> 1 > >> > >> > >> I am not able to reproduce your comments: > >> > >> > for ^2.1..2.5 {print "$_\n";} > >> Range objects are not valid endpoints for Ranges > >>in block at line 1 > >> > >> > for ^2.1 .. 2.5 {print "$_\n";} > >> Range objects are not valid endpoints for Ranges > >>in block at line 1 > >> > >> Would you mind throwing me an REPL example? > >> > >> Many thanks, > >> -T > > On 1/1/21 12:39 AM, Kevin Pye wrote: > > We have established that ^2.1 is a range, meaning all the real numbers > > from 0 to 2.1, not including the 2.1. > > > > What do you expect ^2.1 .. 2.5 to mean, That's a range (the "..") from > > "^2.1", another range to the number 2.5. You can't have a range starting > > with a range, A range is between two numbers. Hence the error message is > > quite correct. > > > > There are four infix operators which create ranges: "..", "^..", "..^" > > and "^..^" > > and the prefix operator "^:"; you're trying to mix two of them. > > > > All of those take numbers as their arguments, not ranges. > > > > Try something like > > > > .say for 2.1 .. 2.5 > > > > You can try > > .say for 2.1 ^.. 2.5 > > > .say for 2.1 .. 2.5 > 2.1 > > > > .say for 2.1 .. ^2.5 > Range objects are not valid endpoints for Ranges >in block at line 1 > > > > and then explain the output. > > Hi Kevin, > > I am trying to get it to work in a "for" loop. > > I am doing something wrong. > > Would you mind sending me the proper syntax > for this from REPL? > > -T > > > > >
Re: for and ^ question
On Fri, 1 Jan 2021 at 18:59, ToddAndMargo via perl6-users mailto:perl6-users@perl.org>> wrote: >> ^ note: ^3 means the integer "just before" 3 (zero is presume to be the >> start point) >> >>3^ means the integer "just after" 3 (an ending point is >> required) >> >> On 12/31/20 10:15 PM, Kevin Pye wrote: > No, it does not. Go back and read what Brad wrote; he was quite explicit. > > Nothing about the range 0 ..^ 3 (for which "^3" is just a short-cut) > says anything about integers. It is the range of numbers (real numbers > if you like) ranging from 0 to 3, but excluding 3. In standard > mathematical notation that would be "[0,3)". If you iterate over the > range then you start with the beginning of the range and keep adding one > until you reach the end (in this case ignoring the final value if it is > equal to the end-point). > > If the range were 0.5 .. 3 then the iterated values would be 0.5, 1.5 > and 2.5. Hi Kevin, My notes were for "for" loops. > for ^2 {print "$_\n";} 0 1 I am not able to reproduce your comments: > for ^2.1..2.5 {print "$_\n";} Range objects are not valid endpoints for Ranges in block at line 1 > for ^2.1 .. 2.5 {print "$_\n";} Range objects are not valid endpoints for Ranges in block at line 1 Would you mind throwing me an REPL example? Many thanks, -T On 1/1/21 12:39 AM, Kevin Pye wrote: We have established that ^2.1 is a range, meaning all the real numbers from 0 to 2.1, not including the 2.1. What do you expect ^2.1 .. 2.5 to mean, That's a range (the "..") from "^2.1", another range to the number 2.5. You can't have a range starting with a range, A range is between two numbers. Hence the error message is quite correct. There are four infix operators which create ranges: "..", "^..", "..^" and "^..^" and the prefix operator "^:"; you're trying to mix two of them. All of those take numbers as their arguments, not ranges. Try something like .say for 2.1 .. 2.5 You can try .say for 2.1 ^.. 2.5 > .say for 2.1 .. 2.5 2.1 > .say for 2.1 .. ^2.5 Range objects are not valid endpoints for Ranges in block at line 1 and then explain the output. Hi Kevin, I am trying to get it to work in a "for" loop. I am doing something wrong. Would you mind sending me the proper syntax for this from REPL? -T
Re: for and ^ question
We have established that ^2.1 is a range, meaning all the real numbers from 0 to 2.1, not including the 2.1. What do you expect ^2.1 .. 2.5 to mean, That's a range (the "..") from "^2.1", another range to the number 2.5. You can't have a range starting with a range, A range is between two numbers. Hence the error message is quite correct. There are four infix operators which create ranges: "..", "^..", "..^" and "^..^" and the prefix operator "^:"; you're trying to mix two of them. All of those take numbers as their arguments, not ranges. Try something like .say for 2.1 .. 2.5 You can try .say for 2.1 ^.. 2.5 and then explain the output. On Fri, 1 Jan 2021 at 18:59, ToddAndMargo via perl6-users < perl6-users@perl.org> wrote: > >> ^ note: ^3 means the integer "just before" 3 (zero is presume to > be the > >> start point) > >> > >>3^ means the integer "just after" 3 (an ending point is > >> required) > >> > >> > > On 12/31/20 10:15 PM, Kevin Pye wrote: > > No, it does not. Go back and read what Brad wrote; he was quite explicit. > > > > Nothing about the range 0 ..^ 3 (for which "^3" is just a short-cut) > > says anything about integers. It is the range of numbers (real numbers > > if you like) ranging from 0 to 3, but excluding 3. In standard > > mathematical notation that would be "[0,3)". If you iterate over the > > range then you start with the beginning of the range and keep adding one > > until you reach the end (in this case ignoring the final value if it is > > equal to the end-point). > > > > If the range were 0.5 .. 3 then the iterated values would be 0.5, 1.5 > > and 2.5. > > > Hi Kevin, > > My notes were for "for" loops. > > > for ^2 {print "$_\n";} > 0 > 1 > > > I am not able to reproduce your comments: > > > for ^2.1..2.5 {print "$_\n";} > Range objects are not valid endpoints for Ranges > in block at line 1 > > > for ^2.1 .. 2.5 {print "$_\n";} > Range objects are not valid endpoints for Ranges > in block at line 1 > > Would you mind throwing me an REPL example? > > Many thanks, > -T > > >