Learnosity Logo
Learnosity Banner Image

Extracting from sound from Flash (aka NellyMoser)

A current project that we are working on requires us to be able to record sound via a flash plugin. Initially I thought it would be nice and easy as I've seen demos of both video and audio broadcasting - however, the one big problem is that the current flash client only allows you to record video to a netstream, you can't get any access to it in the flash player.

So you need something like Flash Media Server or Red5 to record it.

However, once you record it to the server it is an flv and the audio codec is stored as a NellyMoser encoded audio portion. This codec is not supported by many applications and after a quick google found the nelly2pcm project on google code.

This will convert a flv sound file to a raw pcm file - which you can then do useful stuff with. So here's how to do it on a Ubuntu machine.

$ tar -xjvf nelly2pcm.tar.bz2
$ cd nelly2pcm
$ make
cc -Wall -c -o nelly2pcm.o nelly2pcm.c
cc -Wall -c -o nelly.o nelly.c
cc -Wall -c -o nelly_tables.o nelly_tables.c
cc -Wall nelly2pcm.o nelly.o nelly_tables.o -lm -o nelly2pcm
You should now have a nelly2pcm executable file in this directory.

You can run it as follows:

$ ./nelly2pcm test.flv > test.raw
mono Nellymoser stream with 16-bit samples at 44kHz

This will create a raw sound file with no headers and output the line above which you'll need for the next part.

To play this file back you can use sox (apt-get install sox)

$ play -r 44100 -c 1 -2 -s test.raw

If you've got all the options correct then this will play the file back. Once you got it correct you can then use sox to create a wav file which is essentially the same except that it has a header which contains all the settings (eg bitrate etc)

$ sox -r 44100 -c 1 -2 -s test.raw test.wav

From a wav you can convert to whatever you like. I'm looking forward to the Flash Player 10 release as this messing will no longer be necessary as it will support encoding with the free Speex codec.

Cheers, Mark

Update:

In the 12 hours since I wrote this post it appears that a DMCA takedown notice has been served on the nelly2pcm site and google have taken it down. I've no idea if it's related to this post or not and no details are available yet on the chillingeffects site but hopefully it will be updated shortly. As I mentioned earlier, I can't wait for flash 10 with the speex codec so we don't have to use Nellymoser, well done Adobe for including it.

"Logical AND" with flex binding in mxml

While making a small change to a view in one of our flex app's I came across the following little problem.

Initially there was a single parameter binding which set the button enabled, eg:

<mx:Button enabled="{model.user.allowSomething}" label="Do Something">

The business requirements changed and we need to have a global setting as well as a user setting, so now the setting had to be globally enabled and the user had to have access to it.

My 1st attempt was this:

<mx:Button enabled="{model.settings.allowSomething && model.user.allowSomething}" label="Do Something">

However, this gave the following error:

The entity name must immediately follow the '&' in the entity reference.

This you may recognise as an XML formatting error. After a quick google I came across a bug in the adobe bug tracker related to this (BTW I love that this is now open and searchable) which explained the workaround. XML escape the characters - which feels ugly when writing code, but it does make sense.

So the code now becomes:

<mx:Button enabled="{model.settings.allowSomething &amp;&amp; model.user.allowSomething}" label="Do Something">

I also came across another way of handling it using the ternary operator which is very clever but I think it is even less readable than the escaped XML characters.

Cheers, Mark

Flex/AIR embedded fonts - Exception during Transcoding - Solved

I've come across this error a number of times:

exception during transcoding: Unexpected exception encountered while reading font file '/C:/Documents and Settings/markl/My Documents/Flex Builder 3/DexterNorthCode/src/assets/DejaVuSans-Bold.ttf'

It can be very frustrating as there is not much information to be gleaned from the error messages and the whole font area is very murky and complicated.

There are a number for reasons that this error will occur

  • If you reference the wrong file
  • If you specify the fontStyle or fontWeight wrong
  • or most frustratingly if the font manager can't interpret the font correctly.

After grappling with this problem for I while and after much reading I realised that there are 3 different "font managers" that transcode fonts in AS3. These are:

  • flash.fonts.JREFontManager
  • flash.fonts.AFEFontManager
  • flash.fonts.BatikFontManager

The different font managers have different capabilities and should be automatically selected to choose the best one. However, this is not always the case.

You can force the compiler to use a specific manager by appending the following to the compiler arguments.

Project->Properties->Flex Compiler->Additional compiler arguments:

-managers=flash.fonts.AFEFontManager

This forces the use of the AFEFontManager which seems to have the best support for fonts and is the one being most actively developed.

Rich formatting for PDF's directly from Actionscript

I've blogged previously about the AlivePDF libraries which allow you to create PDF's directly from Actionscript.

I've been using them for a project and all was going well until we hit a limitation in the libraries. We can do rich formatting and we can do automatic line wrapping and pagination, but we can't do the both together.

Screenshot of generated pdf

This would have been an enormous problem if this was a piece of commercial software as we would be completely at the mercy of the creators. However, as it is Open Source we have access to the code and we can extend it as we see fit.

And that's exactly what we did. I've added a new version of the writeText() method called very imaginatively writeText2().

It takes the same parameters but instead of taking a standard string it will render a string that has html markup. I.e. you can put a <b> tag in and your text will be bold. Eg:

// This will write the following text with appropriate styling and word wrapping
pdf.writeText2 ( 15, 'A long <u>piece</u> of <b>text</b> in <center>1111 center 1111 2222 center 2222 3333 center 3333 <b>BOLD TEXT</b> 4444 center 4444</center>standard format that should wrap by the time I finish this. AAAAAAAAAAAAAAAABBBBBBBBBBBBCCCCCCCCCCCCCCAAA <i>Italic text</i>. <b>Some bold text</b>. And now for some <b><i>Bold and Italic Text</i></b>. And back to normal. Then a line break<br/> That\'s All.'   );

For the curious you can download a sample document generated by it.

It currently supports the following tags:

  • <b> Make it bold
  • <u> Underline it
  • <i> Make it italic
  • <center> Center it
  • <br /> Add a line break

The code still needs a some cleanup and more testing but it seems to be reliable now.

The two files that were changed are available for download. Or alternatively you can download the full version with changes included. Give it a try and let me know what you think.

Cheers, Mark Lynch

Job Vacancy Sydney AU - Graduate or Junior OO Programmer

We're looking for a Computer Science Graduate or similar with strong Object Oriented programming skills and the ability to grasp cutting edge technologies quickly.

If you are looking to work with the latest technogies and are a motivated self starter with a positive "can do" attitude this is the job for you. The ability to take problems and deliver solutions is a must.

There will be significant on the job learning as we are always pushing the boundaries and using the latest and greatest technologies. We are currently working on projects using Actionscript/Flex, ColdFusion, PHP, and Javascript, and are leveraging technologies such as VOIP, SMS, Instant Messenger (Jabber XMPP) to deliver cutting edge solutions.

Suitable applicants will have a Bachelors Degree in Computer Science or Engineering, or similar tertiary qualification. Remuneration commensurate with experience.

Responsibilities would include:

  • Developing new functionality for Asterisk and VOIP applications
  • Creating Rich Internet Applications with Adobe Flex
  • Creation of Desktop applications with Adobe AIR
  • Design and development of new Web applications

Must haves:

  • A robust foundation in Object Oriented programming
  • Demonstrated experience in at least one OO language
  • Motivation to learn and push the boundaries
  • Understanding of XHTML and CSS

Preferable:

  • Experience with PHP, ColdFusion, Farcry CMS, XML, Web Standards etc
  • Competency using linux-based tools (SSH, bash, etc)
  • Familiar with using source control tools (Subversion, etc)
  • Familiarity with Actionscript or Flash

This role may be full time, part-time or on a contract basis depending on the candidates skills and experience. You will be working in a casual workplace with flexible hours in the centre of Sydney.

If this sounds like the job for you email your resume to mark@lynchconsulting.com.au if interested - no agencies please.

Getting Flex 4.0 up and running on Ubuntu

I came across a blog entry today from Mike Morearty about the flex 4 source tree.

It also mentioned the swfdump tool which looked interesting

I downloaded it and went to the bin directory to try swddump but it didn't work straight away complaining about a missing jar file.

I thought this would mean a lot of pain to get it all compiling but I was very surprised. Here were the steps to get it working on Ubuntu 8.04 Hardy Heron.

Step 1

Get the code from the repository

This will check out the code to a directory called flex4 under your current directory. I'm assuming you have Subversion installed but if you don't you'll need to run this first.
sudo apt-get install subversion

Get the tools to compile flex

sudo apt-get install ant ant-optional sun-java6-jdk
That wasn't hard now was it?

Compile

Go into the correct directory and call "ant" which will use the build.xml to build it all.
cd flex4
ant

Some couple of minutes later you should get the following message

BUILD SUCCESSFUL
Total time: 2 minutes 41 seconds

Now you have a build of Flex4. Next step is to figure out how to configure Flex Builder to use the new compiler.

NOTE: This is not a finished version of Flex4 yet. Just the work in progress.

Cheers, Mark

PDF Generation in Actionscript - AlivePDF

The ability to create PDF documents natively in Actionscript has been something I've been looking for for a while. During the early stages of the AIR program I was really hoping that it would be included in it, however that was not to be.

Today however, I found the AlivePDF project which is a Native Actionscript 3 library for generating PDF's. It is open source, and now released under the liberal MIT licence which means it can be used in any project of your liking - as long as you keep the attributions - which is definitely fair enough.

From my perspective it means that I can use the library for some open source projects as well as for projects which are not open source, but means I'll have more time to work on it.

I've only scratched the surface of the AlivePDF codebase but so far it seems to work really well - and should make it possible to generate professional output from Flex and AIR applications.

An example of how to generate a simple PDF:

pdf = new PDF();
pdf.setDisplayMode (Display.FULL_PAGE,Layout.SINGLE_PAGE);
pdf.addPage();
pdf.setFont( FontFamily.ARIAL );
pdf.addText("My absolutely positioned text",1,10);
pdf.setFont( FontFamily.ARIAL , "", 32);
pdf.writeText ( 20, "Some flowing text that will go across pages");   

//Save the pdf as a byte array //to send to server or use AIR to write to a local file var bytes:ByteArray = pdf.savePDF(Method.LOCAL);

Thanks Thibault for the great software and I look forward to using and hopefully contributing over the coming months.

Note: Please see updated entry on this - my first contribution to the codebase which covers rich text formatting of created pdfs

Cheers, Mark

Gmail, Docs, Calendar and Analytics standalone with Prism

I came across Mozilla Prism the other day and while I'm still deciding if it's going to be a permanent addition to my machine so far so good.

Screenshot of Prism Gmail Prism is a cut down version of Mozilla which is designed to run single sites from icon - what's the use of that you may ask? Well it allows you to have an icon on your desktop for Gmail or Google Calendar or docs or analytics and get to it nice and quickly.

It also free's up some much needed screen real-estate as all the other toolbars relevant for a web-developers browser can get in the way and are not used when you are using you email and calendar.

Additionally - as web developer I tend to restart firefox more often than some - and having my email seperated from that is nice.

Give it a try and see if you like it. On Ubuntu Hardy you can do the following to install it:

#install calendar
sudo apt-get install prism-google-calendar
#install google docs
sudo apt-get install prism-google-docs
#install gmail
sudo apt-get install prism-google-mail
#install analytics
sudo apt-get install prism-google-analytics

On other platforms (windows,mac or other linux versions) you can go to the Prism site and download it.

For the different applications check out the Bundles section or the User contributed bundles section.

Obviously this shares a lot of similarities with the adobe AIR platform albeit not as full featured. It will be interesting to see what further development plans there are for the prism platform.

Cheers, Mark

CFMX - SOAP vs REST benchmarks

One of the applications that we have developed relies quite heavily on web services and I've been doing some benchmarking to figure out how we can improve the performance of it.

Currently the application consists of a AIR/Flex frontend and a CF backend which is using SOAP web services to communicate. I wanted to understand the level of overhead that the SOAP layer added to each coldfusion request and understand if it would be beneficial to move away from using SOAP to using a REST type direct XML format.

Test 1: SOAP CFC vs REST CFM

Initally I created two files which were a very simple hello world example to test each scenario.

soapservice.cfc:

<cfcomponent>
<cffunction name="hello" access="remote" returntype="string">
   <cfreturn 'hello world'>
</cffunction>
</cfcomponent>

and the CFM/REST version

xmlservice.cfm:

<cfsetting enablecfoutputonly="true">
<cfcontent reset="true" type="text/xml">
<cfparam name="url.method" default="">
<cfswitch expression="#url.method#">
   <cfcase value="hello">
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>Hello World</str></cfoutput>
   </cfcase>
   <cfdefaultcase>
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>Unknown Method</str></cfoutput>
   </cfdefaultcase>
</cfswitch>

The results of the load tests were striking

The rest version of the code was 4 to 5 times faster, which meant 1000 second per minute instead 200 requests per second.

However, looking at the code I thought it was an unfair comparison as the SOAP one was using OO-style code which was more maintainable. I'm very much an OO person so I didn't want to have to live with horribly unmaintainable code just to get performance.

Test 2: SOAP CFC vs REST CFM with CFC

I created a new version of the CFM file which this time leveraged the soapservice.cfc which meant I could use the same code but bypass the seemingly very slow SOAP layer in Coldfusion.

xmlservicewithcfc.cfm:

<cfsetting enablecfoutputonly="true">
<cfcontent reset="true" type="text/xml">
<cfparam name="url.method" default="">
<cfswitch expression="#url.method#">
   <cfcase value="hello">
      <cfset oSS = createObject("component","soapservice")>
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>#oSS.hello()#</str></cfoutput>
   </cfcase>
   <cfdefaultcase>
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>Unknown Method</str></cfoutput>
   </cfdefaultcase>
</cfswitch>

So this version now uses a REST type request but leverages the CFC code for the functionality of "hello world".

This was not quite as good performance as the pure CFM code with only 3 to 4 times the performance of the SOAP version - but still not bad at all.

Test 3: SOAP CFC vs REST CFM with CFC with caching

One thing that is known to be reasonably costly in CF is the instantiation of CFC objects. A typical way to avoid this is to instantiate the objects once and then store them in the persistent application scope. This technique will work for lots of the code I am looking to optimise so I wanted to see how much impact it would have.

xmlservicewithcfccached.cfm:

<cfsetting enablecfoutputonly="true">
<cfcontent reset="true" type="text/xml">

<cfapplication name="xmlservicewithcfcached" sessionmanagement="false" clientmanagement="false">

<cfparam name="url.method" default="">
<cfswitch expression="#url.method#">
   <cfcase value="hello">   
      <cfif NOT structKeyExists(application,'oSS')>
         <cfset application.oSS = createObject("component","soapservice")>
      </cfif>
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>#application.oSS.hello()#</str></cfoutput>
   </cfcase>
   <cfdefaultcase>
      <cfoutput><?xml version="1.0" encoding="utf-8"?><str>Unknown Method</str></cfoutput>
   </cfdefaultcase>
</cfswitch>

The performance of this version of the code was almost identical to the 1st version - i.e. 4 to 5 times faster than using the SOAP version but it more easily maintainable.

Is this a valid benchmark?

In a word no - in the strict sense of a reproducible benchmark. It was done on my development laptop as I don't have lots of spare machines lying around.

The specs of the machine are as follows:

  • Intel Core 2 Duo T7200 @ 2GHz
  • 3GB Ram
  • Ubuntu 7.10 (gutsy) with standard 2.6.22-14-generic kernel
  • Coldfusion 7.0.2 - Multiserver install - default config
  • Apache JMeter 2.3.1 for load testing

Each thread in the tests ran 10,000 loops - so for example the tests where I ran 50 threads would be 10,000 x 50 = 500,000 requests.

The entire test was conducted over the course of one day and there were no reboots during the tests. Mostly the same programs were running but it was connected to the internet so minor variations in load and traffic could have affected the results.

What about CF8?

After I finished the testing on CF7 (which is what we currently have on our Production servers) I tried it out on the CF8 Install to see how it compared - the details are detailed below.

Show me the stats

So here are the pretty stats and charts that I created to understand all the data:

Graph 1:

Table 1 - figures for Graph 1:

Graph 2:

Table 2 - figures for Graph 2:

Need more stats?

I have also uploaded the spreadsheet that I created to generate these stats in the original OpenDocument format and also as an Excel file.

Conclusion

For me - I'll be definitely looking at using the REST methods further on any high traffic sites where I might previously have used SOAP.

What are we gaining

  • Lots of performance - a 5 fold performance increase can't be ignored.
  • Smaller data being transferred as no SOAP envelope overhead
  • More control over data transferred
  • Ability to use conventional debugging and caching techniques

What are we giving up

  • Automatic handling of complex objects
  • Lots of overhead

I'd love to hear your thoughts on this - what else am I giving up?

Cheers, Mark

Adding Mime-type for Adobe AIR Packages on Ubuntu

If you've just put you Adobe AIR package on you server and you get something that looks like the picture below then you need to add a mime type so that apache can tell your browser what type of file it is.

The reason that apache doesn't already know about it is that the Adobe AIR format has only just been released.

To fix up a Ubuntu server all you need to do is add the following line to the /etc/mime.types file:

application/vnd.adobe.air-application-installer-package+zip air

Then restart apache with:

sudo /etc/init.d/apache restart

All done. I'm sure that the mime type will be included going forward so this won't be a problem.