Re: for and ^ question

2021-01-01 Thread Patrick R. Michaud
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

2021-01-01 Thread ToddAndMargo via perl6-users

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

2021-01-01 Thread Brad Gilbert
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

2021-01-01 Thread Vadim Belman
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

2021-01-01 Thread Nathan Gray
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

2021-01-01 Thread David Santiago




> 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

2021-01-01 Thread ToddAndMargo via perl6-users

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

2021-01-01 Thread Kevin Pye
..^ 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-us...@perl.org> wrote:

> >> On Fri, 1 Jan 2021 at 18:59, ToddAndMargo via perl6-users
> >> mailto:perl6-us...@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

2021-01-01 Thread ToddAndMargo via perl6-users
On Fri, 1 Jan 2021 at 18:59, ToddAndMargo via perl6-users 
mailto:perl6-us...@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

2021-01-01 Thread Kevin Pye
 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-us...@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
>
>
>