Any microphone action script code which indicates a progress bar when there is activity on microphone
here's some code you can use:
it uses the graphics API to draw the indication of volume
<?xml version="1.0" encoding="utf-8"?><mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="450"
height="450"
creationComplete="creationComplete_Handler()">
<mx:Script>
<![CDATA[
import flash.media.Microphone;
import flash.events.ActivityEvent;
import flash.events.Event;
import flash.events.StatusEvent;
private var _mic:Microphone;
private function creationComplete_Handler():void
{
_mic = Microphone.getMicrophone();
_mic.setLoopBack(true);
_mic.addEventListener(Event.ACTIVATE, mic_ActivateEventHandler);
_mic.addEventListener(StatusEvent.STATUS, mic_StatusEventHandler);
_mic.addEventListener(ActivityEvent.ACTIVITY, mic_ActivityEventHandler);
}
private function mic_ActivateEventHandler(e:Event):void
{
lblStatus.text = "mic active!";
}
private function mic_StatusEventHandler(e:StatusEvent):void
{
trace("ststus event: " + e.toString());
}
private function mic_ActivityEventHandler(e:ActivityEvent):void
{
trace("Activity Event");
addEventListener(Event.ENTER_FRAME, mic_EnterFrame_EventHandler);
}
private function mic_EnterFrame_EventHandler(e:Event):void
{
lblMicLevel.text = "Mic Level :"+_mic.activityLevel.toString();
micLevelCanvas.graphics.clear();
micLevelCanvas.graphics.beginFill(000000, 1);
micLevelCanvas.graphics.drawRect(0, 0, (_mic.activityLevel * 2), 20);
micLevelCanvas.graphics.endFill();
}
]]>
</mx:Script>
<mx:Label x="10" y="10" id="lblStatus"/>
<mx:Canvas x="10" y="36" width="200" height="20" id="micLevelCanvas" />
<mx:Label x="10" y="64" id="lblMicLevel"/></mx:Application>
Related
I'm having a sizing issue with a canvases located inside an HBox. It seems "_graphic", "_border" and "_fill" canvases (in com.example.ThingRenderer.mxml) do not get measured at the same time as all the other measurements inside the renderer. However, this problem is only observed on the first pass-through. Refer to the images for a visual... 1st image shows the state of the app after it finished loading. 2nd image represents what the screen looks like after the Populate button is clicked. 3rd image shows what happens when the stepper is incremented. The question is how come the drawing in the 3rd image doesn't get rendered once the data is populated into the table?
RendererTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="handleCreationComplete(event)"
>
<mx:Script>
<![CDATA[
import com.example.Thing;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.events.NumericStepperEvent;
private const _thingProvider:ArrayCollection = new ArrayCollection();
private var _thing1:Thing;
protected function handleCreationComplete(event:FlexEvent):void {
_thing1 = new Thing("thingy", 0xff0000, 0.3);
_stepper.value = _thing1.ratio;
}
protected function handlePopulateClick(event:MouseEvent):void {
_thingProvider.addItem(_thing1);
}
protected function handleStepperChange(event:NumericStepperEvent):void {
_thing1.ratio = event.value;
}
]]>
</mx:Script>
<mx:VBox>
<mx:Button label="Populate" click="handlePopulateClick(event)" />
<mx:NumericStepper id="_stepper" minimum="0" maximum="1" stepSize="0.01" change="handleStepperChange(event)" />
<mx:AdvancedDataGrid dataProvider="{_thingProvider}" variableRowHeight="true" width="100%" height="100%">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name" />
<mx:AdvancedDataGridColumn headerText="Display"
width="150" sortable="false"
itemRenderer="com.example.ThingRenderer"
/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</mx:Application>
com.exampleThingRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas
xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off"
>
<mx:Script>
<![CDATA[
import mx.binding.utils.ChangeWatcher;
private var _thing:Thing;
private var _ratioWatcher:ChangeWatcher;
private var _doClearContent:Boolean;
private var _doDrawBorder:Boolean;
private var _doUpdateFill:Boolean;
override public function set data(value:Object):void {
if(value && value is Thing) {
_thing = Thing(value);
if(_ratioWatcher) {
_ratioWatcher.unwatch();
}
_ratioWatcher = ChangeWatcher.watch(_thing, "ratio", handleRatioChanged);
_doClearContent = false;
_doDrawBorder = true;
_doUpdateFill = true;
_graphic.invalidateSize();
_border.invalidateSize();
}
else {
_doClearContent = true;
_doDrawBorder = false;
_doUpdateFill = false;
}
super.data = value;
}
private function handleRatioChanged(event:Event):void {
_doUpdateFill = true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
if(_doClearContent) {
_container.visible = false;
_container.includeInLayout = false;
_doClearContent = false;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(_doDrawBorder) {
trace("_thingContainer.width="+_container.width, "_thingGraphic.width="+_graphic.width, "_thingBorder.width="+_border.width);
_border.graphics.clear();
_border.graphics.moveTo(0, 0);
_border.graphics.lineStyle(1, _thing.color);
_border.graphics.lineTo(_border.width, 0);
_border.graphics.lineTo(_border.width, _border.height);
_border.graphics.lineTo(0, _border.height);
_border.graphics.lineTo(0, 0);
_doDrawBorder = false;
}
if(_doUpdateFill) {
_percentage.text = Math.round(_thing.ratio * 100.0) + "%";
_fill.graphics.clear();
_fill.graphics.beginFill(_thing.color);
_fill.graphics.drawRect(0, 0, _fill.width * _thing.ratio, _fill.height);
_doUpdateFill = false;
}
}
]]>
</mx:Script>
<mx:HBox id="_container" width="100%" paddingLeft="5" paddingTop="5" paddingRight="5" paddingBottom="5">
<mx:Label id="_percentage" width="45" />
<mx:Canvas id="_graphic" width="100%" height="15">
<mx:Canvas id="_border" x="0" y="0" width="100%" height="100%" />
<mx:Canvas id="_fill" x="0" y="0" width="100%" height="100%" />
</mx:Canvas>
</mx:HBox>
</mx:Canvas>
com.example.Thing.as
package com.example {
public class Thing {
[Bindable] public var name:String;
[Bindable] public var color:uint;
[Bindable] public var ratio:Number;
public function Thing(name:String, color:uint, ratio:Number) {
this.name = name;
this.color = color;
this.ratio = ratio;
}
}
}
All this happens because you can't use width and height properties in updateDisplayList, they are not updated yet. Make separate component (e.g. ThingProgressBar) and put drawing logick inside it, that will solve everything:
package
{
import mx.core.UIComponent;
public class ThingProgressBar extends UIComponent
{
private var _ratio:Number;
public function get ratio():Number
{
return _ratio;
}
public function set ratio(value:Number):void
{
_ratio = value;
invalidateDisplayList();
}
override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
graphics.clear();
if (unscaledWidth > 0 && unscaledHeight > 0)
{
graphics.lineStyle(1, 0xFF0000);
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, unscaledWidth * ratio, unscaledHeight);
graphics.endFill();
}
}
}
}
So your renderer might look like this:
<mx:HBox
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
horizontalScrollPolicy="off" verticalScrollPolicy="off" xmlns:local="*"
>
<fx:Script>
<![CDATA[
[Bindable] private var _thing:Thing;
override public function set data(value:Object):void
{
_thing = value as Thing;
super.data = value;
}
]]>
</fx:Script>
<mx:HBox width="100%"
paddingLeft="5" paddingTop="5"
paddingRight="5" paddingBottom="5">
<mx:Label text="{_thing.name}" width="45" />
<local:ThingProgressBar width="100%" height="15"
ratio="{_thing.ratio}"/>
</mx:HBox>
</mx:HBox>
I removed watcher. Binding by watcher is considered a bad practice, use mxml binding or events instead.
I removed two Canvases with separated border and fill - they can be cobined together.
I used UIComponent instead of Canvas. Don't use containers unless you need layout, they are heavy.
I used HBox instead of Canvas in renderer because I like boxes more :) But you can't avoid using second container in renderer if you need custom styles since List overwrites renderer's stylesheet.
In the following code how to mute the speakers
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="300"
height="100"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.media.*;
import flash.net.NetStream;
private var myMic:Microphone;
private var recordingState:String = "idle";
private function init():void {
myMic = Microphone.getMicrophone();
myMic.setSilenceLevel(0);
myMic.rate = 44;
myMic.gain = 100;
myMic.setUseEchoSuppression(true);
micLevel.visible = true;
//Security.showSettings(SecurityPanel.MICROPHONE);
myMic.setLoopBack(true);
if (myMic != null)
{
myMic.setUseEchoSuppression(true);
micLevel.setProgress(myMic.activityLevel, 100);
addEventListener(Event.ENTER_FRAME, showMicLevel);
//micLevel.setProgress(myMic.activityLevel, 100);
}
}
private function showMicLevel(event:Event):void{
switch (recordingState){
case "idle" :
micLevel.setProgress(myMic.activityLevel, 100);
break;
}
}
]]>
</mx:Script>
<mx:ProgressBar x="0" y="36" mode="manual" id="micLevel" label="" labelPlacement="bottom" width="100" fontSize="10" fontWeight="normal"/>
If you just want to disble the voice from microphone to come into the speakers do
myMic.setLoopBack(false);
This will disable the sound detected by microphone to be played in the speakers.
EDIT1:
//use the function to disable sound completely.
private function disableSound():void
{
var newSoundTransform:SoundTransform=new SoundTransform();
newSoundTransform.volume=0;
this.soundTransform=newSoundTransform;
}
Call the above function in init() function.
This will completely disable all sounds coming from the application.
Can any one indicata me a small piece of code for making this progress bar move on mic activitylevel. i.e, When spoken on the microphone the progressbar should indicate it.Also which works on internet explorer
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="300"
height="100"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.net.NetStream;
private var myMic:Microphone;
private var recordingState:String = "idle";
private function init():void {
myMic = Microphone.getMicrophone();
myMic.setSilenceLevel(0);
myMic.rate = 44;
myMic.gain = 100;
micLevel.visible = true;
Security.showSettings(SecurityPanel.MICROPHONE);
myMic.setLoopBack(true);
if (myMic != null)
{
myMic.setUseEchoSuppression(true);
micLevel.setProgress(myMic.activityLevel, 100);
addEventListener(Event.ENTER_FRAME, showMicLevel);
//micLevel.setProgress(myMic.activityLevel, 100);
}
}
]]>
</mx:Script>
<mx:ProgressBar x="0" y="36" mode="manual" id="micLevel" label="" labelPlacement="bottom" width="100" fontSize="10" fontWeight="normal"/>
</mx:Application>
You need to add a callback function for the event. You have it defined as showMicLevel but you have no implementation of that function.
private function showMicLevel(e: Event):void{
micLevel.setProgress(myMic.activityLevel, 100);
}
In the below code sometimes when microphone is not connected some noise is generated and the system just keeps on buzzing the same sound.Whats wrong with the code below and how to reduce the unwanted noise. Should i set myMic.setLoopBack(false) in the below code
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="300"
height="100"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flash.net.NetStream;
private var myMic:Microphone;
private var recordingState:String = "idle";
private function init():void {
myMic = Microphone.getMicrophone();
myMic.setSilenceLevel(0);
myMic.rate = 44;
myMic.gain = 100;
myMic.setUseEchoSuppression(true);
micLevel.visible = true;
//Security.showSettings(SecurityPanel.MICROPHONE);
myMic.setLoopBack(true);
if (myMic != null)
{
myMic.setUseEchoSuppression(true);
micLevel.setProgress(myMic.activityLevel, 100);
addEventListener(Event.ENTER_FRAME, showMicLevel);
//micLevel.setProgress(myMic.activityLevel, 100);
}
}
private function showMicLevel(event:Event):void{
switch (recordingState){
case "idle" :
micLevel.setProgress(myMic.activityLevel, 100);
break;
}
}
]]>
</mx:Script>
<mx:ProgressBar x="0" y="36" mode="manual" id="micLevel" label="" labelPlacement="bottom" width="100" fontSize="10" fontWeight="normal"/>
</mx:Application>
Try making myMic.silenceLevel(20) or some higher integer and check.
This should resolve the issue.
I'm using http://code.google.com/p/flex-iframe/ for showing wikicontent in a flex app.
<?xml version="1.0"?>
<mx:TitleWindow
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:components="components.*"
title="Hjälp"
showCloseButton="true"
close="close();"
styleName="Popup"
paddingBottom="0"
paddingLeft="0"
paddingRight="0"
paddingTop="0"
width="700"
height="500">
<mx:Script>
<![CDATA[
import mx.core.Application;
import mx.managers.PopUpManager;
import offerta.Config;
import offerta.monkeywrench.Icons;
import offerta.utils.printf;
import flash.utils.setTimeout;
import flash.display.DisplayObject;
private static var _popup:HelpPopup = null;
[Bindable]
public var callback:Function;
[Bindable]
public var key:String;
private function close(cancel:Boolean = true):void
{
PopUpManager.removePopUp(this);
if(callback!=null) callback();
}
public static function create():HelpPopup
{
HelpPopup._popup =
HelpPopup(PopUpManager.createPopUp(DisplayObject(Application.application),
HelpPopup, true));
HelpPopup._popup.visible = false;
return HelpPopup._popup;
}
public function show():void
{
PopUpManager.centerPopUp(HelpPopup._popup);
this.visible = true;
setTimeout(function():void {
refresh();
},500);
}
public function refresh():void
{
if(!!key)
{
frameMain.label = key;
frameMain.source = printf(Config.DOCUMENTATION_URL,key);
}
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%" paddingBottom="0" paddingLeft="0"
paddingRight="0" paddingTop="0">
<mx:ApplicationControlBar width="100%">
<mx:HBox width="100%" id="pnlToolbar" horizontalGap="0">
<mx:LinkButton
icon="{Icons.refresh}"
click="refresh();"/>
<mx:LinkButton
icon="{Icons.previous}"
click="frameMain.historyBack()"/>
<mx:LinkButton
icon="{Icons.next}"
click="frameMain.historyForward()"/>
</mx:HBox>
</mx:ApplicationControlBar>
<components:IFrame id="frameMain"
loadIndicatorClass="components.IFrameLoadingIndicator"
width="100%"
height="100%"/>
</mx:VBox>
<mx:ControlBar>
<mx:Spacer width="100%"/>
<mx:Button
width="80"
height="30"
label="Stäng"
click="close();"/>
</mx:ControlBar>
</mx:TitleWindow>
When displaying the window: In Ie. it works perfectly, but in FF the
content flashes quickly and then the iframe becomes blank?
I answered you on the bug you opened on the project site ;)
I had missed to add wmode=opaque and it works in FF. Only problem is that flex loadingindicator isn't showing.