KamaeliaNuts & Bolts | Components | Tools | Cookbook | Systems
wiki:( guest738242, Dev Console, Index, Recent, Edit )
So you've built your components and wired them up using Pipelines and Graphlines . But what do you do if you want to create or initialise a component at runtime?
Perhaps you can't know the value of some arguments until you start reading that input file. Or maybe you want to process several streams of data in sequence, but the component you want to use isn't designed to process several streams back to back. This is where a component like the Carousel comes in.
The Carousel gives us a way to create a component on-the-fly in response to being sent a message.from Kamaelia.File.Reading import RateControlledFileReader
from Kamaelia.Audio.Codec.PyMedia.Decoder import Decoder
from Kamaelia.Audio.PyMedia.Output import Output
from Kamaelia.Chassis.Pipeline import Pipeline
import sys
mp3filename=sys.argv[1]Pipeline( RateControlledFileReader( mp3filename, readmode="bytes", rate=256000/8),
Decoder("mp3"),
Output(sample_rate=44100, channels=2, format="S16_LE"),
).run()

from Kamaelia.Chassis.Graphline import Graphline
from Kamaelia.Chassis.Carousel import Carouseldef makeAudioOutput(metadata):
return Output( metadata["sample_rate"],
metadata["channels"],
metadata["format"]
)Graphline( READ = RateControlledFileReader( mp3filename, readmode="bytes", rate=256000/8),
DECODE = Decoder("mp3"),
OUTPUT = Carousel( makeAudioOutput ),
linkages = {
("READ", "outbox") : ("DECODE", "inbox"),
("DECODE", "outbox") : ("OUTPUT", "inbox"), ("DECODE", "format") : ("OUTPUT", "next"),
("READ", "signal") : ("DECODE", "control"),
("DECODE", "signal") : ("OUTPUT", "control"),
}
).run()
{ "sample_rate" : 44100, "channels":2, "format":"S16_LE" }
We've also written a function makeAudioOutput(). When called with the message as its argument; it returns a new Output component set up with the right sample rate, number of channels, and format.
We give this function to the Carousel. Note that we don't call it - we just give it the function. The Carousel calls it when it receives a message on its "next" inbox and therefore needs to create the component:


We can do this by using a Chooser component for the playlist and putting our existing player inside a Carousel. When all the player components finish, our Carousel will send out a "next" message from its "requestNext" outbox, which we can use to cause our Chooser to send back the next filename:

Notice that we can also wire up the "signal" and "control" boxes, so that when the Chooser has no more names in its playlist, it can tell our player Carousel to shut down.
So now lets build this! First, lets make a function that we will give to the Carousel for it to use to create our player:
def makePlayer(mp3filename):
return Graphline(
READ = RateControlledFileReader( mp3filename, readmode="bytes", rate=256000/8),
DECODE = Decoder("mp3"),
OUTPUT = Carousel( makeAudioOutput ),
linkages = {
("READ", "outbox") : ("DECODE", "inbox"),
("DECODE", "outbox") : ("OUTPUT", "inbox"), ("DECODE", "format") : ("OUTPUT", "next"),
("", "control") : ("READ", "control"),
("READ", "signal") : ("DECODE", "control"),
("DECODE", "signal") : ("OUTPUT", "control"),
("OUTPUT", "signal") : ("", "signal"),
}
)
from Kamaelia.Util.Chooser import ForwardIteratingChooser ForwardIterating
filenames = argv[1:]
Graphline( PLAYLIST =Chooser(filenames),
PLAYER = Carousel( makePlayer, make1stRequest=True ),
linkages = {
("PLAYER", "requestNext") : ("PLAYLIST", "inbox"),
("PLAYLIST", "outbox") : ("PLAYER", "next"),
("PLAYLIST", "signal") : ("PLAYER", "control"),
}
).run()
-- 19 Dec 2006 - Matt Hammond
Versions: current , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10
(C) 2005 Kamaelia Contributors, including the British Broadcasting Corporation, All Rights Reserved,
This is an ongoing community based development site. As a result the
contents of this page is the opinions of the contributors of the pages
involved not the organisations involved. Specificially, this page
may contain personal views which are not the views of the BBC.