Gumbo (Flex 4) plays generated sounds in Style
Keywords: FXG, GUI, gumbo, look and feel, skinning, sounds
The past few days I was digging a bit into Gumbo (flex 4 beta). I was happy to see that flex 4 will take a lightweight approach regarding components. Components are stripped down to their most basic behavior and there’s now a clean separation between model, controller and view.
This, in combination with an enhanced state architecture and the newly integrated graphics tag library FXG, makes it a snap to create a custom look and feel in flex (especially when CS4 export or thermo integration will be ready)
Here is a little example of a GUI done in Gumbo (flex 4 beta) to wrap up my sound experiments done earlier.
click here. Needs the latest Flash-Player 10 (rc of 091508).
The GUI for the player is straight forward. It uses some FXG-Elements to draw the background and the description box. Buttons are embedded within containers which serve as a hook for the transitions.
<!-- Player Container --> <Group id="playerContainer" horizontalCenter="0" verticalCenter="0" > <!-- the background --> <Rect id="playerBackground" radiusX="7" radiusY="7" width="380" height="120"> <fill> <LinearGradient rotation="90"> <GradientEntry color="0x606060" alpha="1" ratio="0" /> <GradientEntry color="0x303030" alpha="1" ratio="1" /> </LinearGradient> </fill> </Rect> <Group id="descriptionTextBox" left="120" top="10"> <Rect radiusX="7" radiusY="7" width="250" height="100"> <fill> <LinearGradient rotation="90"> <GradientEntry color="0xffffff" alpha="1" ratio="0" /> <GradientEntry color="0xc0c0c0" alpha="1" ratio="1" /> </LinearGradient> </fill> </Rect> <TextGraphic color="0x606060" fontSize="10" id="descriptionText" paddingLeft="10" paddingRight="10" width="260" fontFamily="Verdana" whiteSpaceCollapse="collapse"> <content> <p fontWeight="bold" fontSize="12" >A silly flash 10 music example</p> <p marginTop="4">Testing flash 10 sound features and the new skinning architecture in Gumbo.</p> <p marginTop="4">Plays dynamically generated sounds based on an absurdly simple sequencer</p> <p marginTop="4">UI done in Flex 4 beta 1 (Gumbo)</p> </content> </TextGraphic> </Group> <Group id="playButton" left="10" top="10"> <Button width="100" selected="false" buttonMode="true" height="100" skinZZ="com.hulstkamp.lab.gumbo.skins.buttons.StandbyButtonSkin" click="togglePlay(event)" /> </Group> <!-- Mute Buttons for voices, included in on-mode, only --> <Group id="mixerButtons" left="10" top="120" alpha="0" > <Button id="drumsBtn" styleName="bassButton" label="Bass" selected="true" buttonMode="true" left="0" width="60" height="60" click="toggleInstrument(event)" /> <Button id="bassBtn" styleName="drumsButton" label="Glass" selected="true" buttonMode="true" left="70" width="60" height="60" click="toggleInstrument(event)" /> <Button id="hookBtn" styleName="hookButton" label="Hook" selected="true" buttonMode="true" left="140" width="60" height="60" click="toggleInstrument(event)" /> </Group> </Group>
Skinning a button in gumbo is simple. Create a skin and apply this to a component via the skinZZ-property (name about to change in final version). Here’s the skin for the MuteButtons. To get a more generic skin I used styles from the hostComponent. Don’t know if this is best practice.
<?xml version="1.0" encoding="utf-8"?> <!-- To get a more generic skin, this class uses some styles (colors and icon) applied to the hostComponent. I'm not sure if styles could be applied to skins directly (sdk 4.0.0.3130). So, this might not be best practice. --> <Skin xmlns="http://ns.adobe.com/mxml/2009"> <Metadata> [HostComponent("flex.component.Button")] </Metadata> <states> <State name="up" /> <State name="over" /> <State name="down" /> </states> <content> <Group> <!-- get width and height via hostComponent --> <Rect radiusX="7" radiusY="7" width="{hostComponent.width}" height="{hostComponent.height}"> <fill> <LinearGradient rotation="90"> <!-- get Styles via the hostComponent. Haven't found a way to apply styles to skins directly --> <!-- if you want binding grap those and make them bindable --> <GradientEntry color="{hostComponent.getStyle('gradientColors')[0]}" color.over="{hostComponent.getStyle('gradientColorsOver')[0]}" alpha="1" ratio="0" /> <GradientEntry color="{hostComponent.getStyle('gradientColors')[1]}" color.over="{hostComponent.getStyle('gradientColorsOver')[1]}" alpha="1" ratio="1" /> </LinearGradient> </fill> </Rect> <TextBox id="labelText" text="{hostComponent.label}" fontFamily="Verdana" fontSize="10" top="10" color="{hostComponent.getStyle('color')}" horizontalCenter="0" > </TextBox> <!-- get the icon via style and show below label --> <BitmapGraphic blendMode="screen" width="50" height="50" scaleX=".5" scaleY=".5" alpha="1" source="{hostComponent.getStyle('icon')}" horizontalCenter="0" bottom="12" /> </Group> </content> </Skin>
Transitions are done in a similar fashion to flex 3.
grab the source here (sdk 4.0.0.3230). UPDATE: Adobe changed the sound api. Use SampleDataEvent.SAMPLE_DATA instead of Event.SAMPLE_DATA for the listener.
External Gumbo resources
Gumbo - Flex SDK - Confluence
Gumbo link roundup at mike chambers
Similar Posts
Turning that Gumbo VSlider into a MixerSlider
Shiny Gumbo Toggle-Buttons. Using Tint and Animate effects in skins.
From cacophony to music. Trying to create bearable evolving music in flash 10 (beta).
Skinning and creating custom rating component in flex 4 (Gumbo)
Custom Component in Flex 4 (Gumbo). A Knob Button - part 1.


November 12th, 2008 at 4:59 am
Andy,
Great work on the sound topic in player 10. I’ve been looking all over the place to find articles about time stretching in flash 10. But no luck yet!
Could you provide any insights into modifying the playback time/duration with altering the pitch? In other words, how can I turn a 4-minute song in Gminor into a 8-minute one without changing the scale?
November 12th, 2008 at 8:03 pm
Wags,
thanks! I haven’t looked into time stretching stuff right now. There is no such thing as timeStretch() for Flash, so you would need to work on the raw sample data anyway. This also means that you can look into generic time stretching algorithms and work from there.
Here you might find good a starting point.