header
ask question
Click here to ask Question Now Its free No registration required. Flash, Flex, Flash Media Server, ActionScript,Adobe Air. Most questions receive a response in an hour.
gt_ebuddy
Points:80
Posts:0

1/5/2011 10:01:04 AM

Title: Sound Record and Play at 8Khz, Recording is OK but Why it is not Playing


Please refer to the question :
http://askmeflash.com/qdetail/1067/capturing-microphone-and-playing-at-lower-sampling-rate
For our project detail refer to :http://ganeshtiwaridotcomdotnp.blogspot.com/2010/12/text-prompted-remote-speaker.html
<><><><><><><><><><><><><><><><><><><><><><><><>
we were initially planning to record the audio at 22 Khz but later we come to conclusion that processing of 22Khz data will be expensive..... and 8Khz will be enough... only 8000 samples per second of audio signal.
the audio is captured at 8Khz and uploaded to server (file bytearray) by modifying AIR's WavWriter class. the saved .wav file is played correctly. but when we are playing the captured byteArray in Client side it is not played correctly.
here is the code :


<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx" width="230" height="95">
	<fx:Script>
		<![CDATA[
			private var mic:Microphone;
			public var byteArrayData:ByteArray;
			public var pcmArray:Array;
			private var snd:Sound;
			import mx.core.FlexGlobals;
			[Bindable] 
			private var micNames:Array = Microphone.names;//bind list of microphones to combo box
			private var rate:int=8;
			protected function recBtn_clickHandler(event:MouseEvent):void{
				if (event.currentTarget.selected == true){
					byteArrayData=new ByteArray();//byteArray variable to store recorded data
					mic = Microphone.getMicrophone(micNamesCombo.selectedIndex);//choose mic from combo list
					//set mic properties
					mic.setUseEchoSuppression(true);
					mic.rate=rate;
					mic.setSilenceLevel(0);
					//mic.setSilenceLevel(silenceLevel,timeOut);
					//set handlers
					mic.addEventListener(StatusEvent.STATUS, statusHandler);
					mic.addEventListener(SampleDataEvent.SAMPLE_DATA, getMicAudio);
					//change components' properties
					event.currentTarget.label = "Stop";
					ply_Btn.enabled=false;
				}
				else{
					//unset getMicAudio handler
					mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, getMicAudio);
					event.currentTarget.label = "Record";
					ply_Btn.enabled=true;
				}
			}
			protected function statusHandler(event:StatusEvent):void{
				//if user denies to open microphone or not available or muted
				if (mic == null) {
					lblErr.text="Error on accessing microphone";	
				}
				if(mic.muted==true){
					lblErr.text="Your Microphone is Muted, unmute it";
				}
			}
			//writes sound data to bytearray
			private function getMicAudio(e:SampleDataEvent): void
			{	
				byteArrayData.writeBytes(e.data);
				//display byteArray length on label
				lblByteCount.text = String(byteArrayData.length);
			}

			 // plays sound

			protected function plyBtn_clickHandler(event:MouseEvent):void{
				if (event.currentTarget.selected == true){
					event.currentTarget.label = "Stop";
					byteArrayData.position = 0;//reset byteArray position to start
					snd = new Sound();
					snd.addEventListener(SampleDataEvent.SAMPLE_DATA, playRecorded);//start playing by invoking SampleDataEvent
					var channel:SoundChannel;//to play, create SoundChannel variable
					channel=snd.play();
					channel.addEventListener(Event.SOUND_COMPLETE, stopPlayback);//when playing is complete
				}
				else{
					event.currentTarget.label = "Play";
					snd.close();
				}
			}	
//<<<<<<<<<<<<<<<<<HERE IS THE PROBLEM>>>>>>>>>>>>>>>>>>>>
			private function playRecorded(e:SampleDataEvent): void{
				if (!byteArrayData.bytesAvailable > 0)//if end; return
					return;
				for (var i:int = 0; i < 8192/(44/rate); i++){
						var sample:Number = 0;
							if (byteArrayData.bytesAvailable > 0) 
								sample = byteArrayData.readFloat();
							//write sample, i.e., play
							for(var j:int=0; j<int((44.0/rate)*2);j++){//4 for 22 khz?for 8khz
								e.data.writeFloat(sample);
							}
					}
			}
//<<<<<<<<<<<<<<<<<WHAT IS THE SOLUTION >>>>>>>>>>>>>>>>>>>>
			private function stopPlayback(e:Event): void{
				ply_Btn.selected=false;
				ply_Btn.label="play";
			}
		]]>
	</fx:Script>
	<mx:ComboBox id="micNamesCombo" dataProvider="{micNames}" x="105" y="11" width="115" toolTip="List of Available Microphones on your computer"/>
	<s:ToggleButton id="rec_Btn" x="10" y="10" width="80" label="Record" click="recBtn_clickHandler(event);"/>
	<s:ToggleButton id="ply_Btn" x="10" y="42" width="80" label="Play" click="plyBtn_clickHandler(event);" enabled="false"/>
	<s:Label x="105" y="42" id="lblByteCount" width="116" height="21" fontSize="16"/>
	<s:Label x="10" y="70" id="lblErr" width="210" height="20" text="" verticalAlign="middle"/>
</s:Group>


We searched for the solution but could not find. And there was nothing mentioned on Adobe documentation. Anyway, Why the code is not working.... what is the actual problem? Please Help us.



1
Shawn
Points: 680
Posts:0
1/6/2011 1:02:47 AM



I will recommend you to use the 12khz atleast. 8khz is not supported by many sound cards on many operating systems. 8khz will sound slow and drowsy in some cases. This is my personal experience not documented by adobe since its not there issue but the sound drivers and OS.

2
Justin
Points: 600
Posts:0
1/6/2011 1:05:22 AM



I had faced a similar issue when using live audio with FMS at 8khz. sytems with win 2000 and MAC operating system did not work with 8khz setting. Ultimately we had to use the higher bit rate.

3
gt_ebuddy
Points: 80
Posts:0
1/6/2011 4:42:52 AM



at 8 khz, the sound was recorded perfectly but it was not playing at all....
and at 11Khz, it played with high pitch.
and finally we decided to use 22Khz..... it is working fine.....
but our concern was just <b>the bigger size of array</b> to process in further steps...

thanks for the reply

4
gt_ebuddy
Points: 80
Posts:0
1/6/2011 4:47:58 AM



i was initially guessing the problem with float value after calculating
 8192/(44/rate) 
and
int((44.0/rate)*2)



            private function playRecorded(e:SampleDataEvent): void{  
                if (!byteArrayData.bytesAvailable > 0)//if end; return  
                    return;  
                for (var i:int = 0; i < 8192/(44/rate); i++){  
                        var sample:Number = 0;  
                            if (byteArrayData.bytesAvailable > 0)   
                                sample = byteArrayData.readFloat();  
                            //write sample, i.e., play  
                            for(var j:int=0; j<int((44.0/rate)*2);j++){//4 for 22 khz?for 8khz  
                                e.data.writeFloat(sample);  
                            }  
                    }  
            }


5
Tim
Points: 0
Posts:0
8/17/2011 12:01:26 PM



Late response but maybe someone else will come across this as I did.

When you use 8000 samples per second, the playRecorded function isn't calling e.data.writeFloat(sample) enough times. It calls it 16379 times instead of 16834 times ( 8192 * 2 ) like the other rates ( 11025, 22050, 44100 ). If you call e.data.writeFloat( 0 ) for the remaining 455 times then you will have a good Sound object for playback.


Post your Reply
Name  

Email

Type your Reply or Answer

Are you human? What is 2+0 



Members Login

Email  
Password
Forgot Password





This website focus on: Flash | Flex | FMS | RED5 | WOWZA | Flash Media Server | Adobe AIR | ActionScript,Flash Solutions | Flash Question | Flash Answers | Flash Developers | Flash Problem, Flash Help, Flash bugs, Flash workaround | Flash Blog | Flex Question Answers | Flash Forum | Flex Development | Actionscript development | Flash development | Adobe AIR development
Copyright © 2008 AskMeFlash.com. All rights reserved. Privacy Policy | Terms & Conditions