diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexFlashToSipTranscoderImp.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexFlashToSipTranscoderImp.java
index 7a7371ec68f0aea62cddc780e7bc8c54ebce9e52..3c52546801fb8444ca9ab016e45741bd474a52cb 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexFlashToSipTranscoderImp.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexFlashToSipTranscoderImp.java
@@ -19,6 +19,11 @@
 package org.bigbluebutton.voiceconf.red5.media.transcoder;
 
 import java.util.Random;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
 
 import org.bigbluebutton.voiceconf.red5.media.FlashToSipAudioStream.TranscodedAudioListener;
 import org.red5.app.sip.codecs.Codec;
@@ -36,9 +41,16 @@ public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
 	private Codec audioCodec;
 	private long timestamp = 0;
 	private final static int TS_INCREMENT = 320; // Determined from PCAP traces.
+	
+	private final Executor exec = Executors.newSingleThreadExecutor();
+	private Runnable audioDataProcessor;
+	private volatile boolean processAudioData = false;
+	private BlockingQueue<SpeexRtpAudioData> audioDataQ;
+	
 	private TranscodedAudioListener transcodedAudioListener;
 	
 	public SpeexFlashToSipTranscoderImp(Codec audioCodec) {
+		audioDataQ = new LinkedBlockingQueue<SpeexRtpAudioData>();
 		this.audioCodec = audioCodec;
         Random rgen = new Random();
         timestamp = rgen.nextInt(1000);
@@ -49,7 +61,13 @@ public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
 		// Just copy the audio data removing the codec id which is the first-byte
 		// represented by the startOffset var.
 		System.arraycopy(audioData, startOffset, transcodedAudio, 0, length);
-		transcodedAudioListener.handleTranscodedAudioData(transcodedAudio, timestamp += TS_INCREMENT);
+		
+		SpeexRtpAudioData srad = new SpeexRtpAudioData(transcodedAudio, timestamp += TS_INCREMENT);
+		try {
+			audioDataQ.offer(srad, 100, TimeUnit.MILLISECONDS);
+		} catch (InterruptedException e) {
+			log.warn("Failed to add speex audio data into queue.");
+		}
 	}
 	
 	public int getCodecId() {
@@ -73,14 +91,33 @@ public class SpeexFlashToSipTranscoderImp implements FlashToSipTranscoder {
 	public void setTranscodedAudioListener(TranscodedAudioListener transcodedAudioListener) {
 		this.transcodedAudioListener = transcodedAudioListener;		
 	}
-
-	@Override
-	public void start() {
-		// do nothing. just implement the interface.
+	
+	private void processAudioData() {
+		while (processAudioData) {		
+			SpeexRtpAudioData srad;
+			try {
+				srad = audioDataQ.take();
+				transcodedAudioListener.handleTranscodedAudioData(srad.audioData, srad.timestamp);
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}  
+		}
 	}
+
+    @Override
+    public void start() {
+    	processAudioData = true;	 
+	    audioDataProcessor = new Runnable() {
+    		public void run() {
+    			processAudioData();   			
+    		}
+    	};
+    	exec.execute(audioDataProcessor);
+    }
 	
 	@Override
-	public void stop() {
-		// do nothing. just implement the interface.
-	}
+    public void stop() {
+    	processAudioData = false;
+    }
 }
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexRtpAudioData.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexRtpAudioData.java
new file mode 100755
index 0000000000000000000000000000000000000000..474bb37cb42aca8c9dcb27525037622623f63f83
--- /dev/null
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/media/transcoder/SpeexRtpAudioData.java
@@ -0,0 +1,12 @@
+package org.bigbluebutton.voiceconf.red5.media.transcoder;
+
+public class SpeexRtpAudioData {
+
+	public final byte[] audioData;
+	public final long timestamp;
+	
+	public SpeexRtpAudioData(byte[] audioData, long timestamp) {
+		this.audioData = audioData;
+		this.timestamp = timestamp;
+	}
+}