|
| Contents | |
| Introduction |
Music Object is an abstraction layer that lies between a Beatnik Player that is instantiated on a page and the HTML page that wishes to control it. It becomes the author's means of communicating with a Beatnik Player instance. Instead of trying to 'speak' directly to the player instance, a Music Object instance is created and linked to the Beatnik Player instance. All communication is then sent to the Music Object instance and is then passed on in the correct manner to the Beatnik Player instance, which could be either the Beatnik Plug-in for Netscape or the Beatnik ActiveX control for Internet Explorer. The way in which one uses Music Object is described in more detail further on in this reference.
The Music Object API is a broad platform for the creation of interactive audio applications on the Web. The comprehensive list of interactive audio features of the Music Object API allows a wide variety of different sonified content to be created, ranging from very straightforward sonified banner ads, to more sophisticated sonified Web sites, and even more elaborate music applications and multimedia experiences.
Some of the types of applications that can be built using the Music Object API include...
There are some limitations to what the Music Object API can do. For example, because of the inherent latencies built into a browser's scripting layer, it wouldn't really be feasible to build a Web-based professional grade synthesizer or music sequencer using the Music Object API.
To see some great examples of the Music Object API in action, check out the Beatnik Showcase.
Within the Music Object code, the connection to the Beatnik Plug-in is made through Netscape's LiveConnect technology, or to the Beatnik ActiveX control through Microsoft's ActiveX scripting. It is not necessary for authors to fully understand this mechanism as this is made fairly transparent through the use of the Music Object code.
Music Object is a JavaScript class that is defined in the JavaScript file called "music-object.js". This JavaScript file is sourced into the HTML document that is to contain Beatnik interactive authoring using the statement
The Music Object abstraction layer performs some very vital functions, without which, authoring for Beatnik would be cumbersome.
MusicObject acts as a wrapper and protection layer around the Beatnik Plug-in's LiveConnect methods. Once a Music Object instance has been created, it is possible in one's authoring to call that Music Object instance's methods directly without having to worry about whether the player is fully instantiated and ready yet. It alleviates the peculiar symptoms associated with LiveConnect JavaScript authoring.
There are a few fundamental differences between LiveConnect scripting and ActiveX scripting that would make programming interactive sonified Web pages more complex if it was left to the author to work around these differences. By managing these differences in the "music-object.js" file (which is sourced into the author's HTML page), the author not only does not need to understand and deal with these differences, but also does not need to have their JavaScript sonification code cluttered by the code that manages the 'wiring' to the player.
The Music Object API extends the Beatnik Player's existing API and offers a few very useful sonification methods. These very methods may make their way into future versions of the player's LiveConnect authoring API.
To get the "music-object.js" JavaScript file, simply right-click on this link (click-and-hold for Mac users). Then, from the menu that pops up, select the 'Save Link As...' or 'Save Target As...' option and save the file as "music-object.js" into an appropriate directory of the local copy of your Web site.
In order to set up an HTML page with the necessary framework for Beatnik interactive authoring, you should follow the guidelines in the section that follows, Starting to use Music Object
YES. You can create as many Music Object instances as you like on the same HTML page. Bear in mind that for each Music Object instance you are expected to embed a Beatnik Player into the page. While there is also no strict limit on the number of Beatnik Player instances living on the same HTML page, there is a maximum limit of sixteen instances that can be playing at the same time (for some older versions of the Beatnik Player, the limit may be eight). If you are going to create many Music Object instances with accompanying players, you should be aware that for each Music Object instance there is a modest minimum amount of memory that is needed on the user's system. The same applies to each Beatnik Player that accompanies a Music Object instance. In addition, when a Beatnik Player loads in its music or audio file, that file must then be contained in the user's memory.
So, while there are no forced limitations on the number of Music Object instances and Beatnik Player instances, you should be careful not to author pages that make such heavy demands on the user's memory resources that the pages then become sluggish and unbearable to use.
For more information, see the section Creating Multiple Instances.
The Beatnik Player offers extensive support for realtime control, offered to authors through the Music Object authoring API. Authors can design startlingly interactive Web pages, demonstrated very effectively in the Beatnik Web site's Showcase area, as well as the Sample Code & Examples contained in this documentation.
To be able to fully unleash the interactive capabilities of Beatnik, you should have a healthy understanding of the JavaScript language. This documentation only assumes knowledge of JavaScript 1.1 and none of the tutorials, sample code, or examples currently make use of the more powerful features of JavaScript 1.2. Browsers that support this version of JavaScript are not yet considered universal enough.
You should setup a bookmark to Netscape's on-line JavaScript documentation to use as a reference as you author using JavaScript.
| What's New In the Latest Version of Music Object? |
IMPORTANT : All the information in this documentation reflects the very latest version of the Music Object API. If you are not using the latest version in your sonification, then you should immediately update your content to use the latest version before using the reference information contained inside this documentation in your authoring.
The Beatnik Music Object Documentation contains a Music Object Version History, where you will be able to find out about the new features and possible issues with the most recent version of the Music Object API, as well as helpful guidelines for updating your sonified content from older Music Object versions.
| Starting to use Music Object |
The following sections will take you step-by-step through the process of setting up a very simple example sonified page. If you observe the basic principles outlined in the sections below, you should be able to start creating your own sonified HTML pages or adding sonification to existing pages.
The core Music Object API is implemented in the "music-object.js" JavaScript file. The first thing you need to do is to make sure that this file is available on your Web site. To get the file, simply right-click on this link (click-and-hold for Mac users). Then, from the menu that pops up, select the 'Save Link As...' or 'Save Target As...' option and save the file as "music-object.js" into the folder that contains the local copy of your Web site.
Once the "music-object.js" file has been copied into your Web site folder, you then need to source the file into the Web page you wish to sonify. This is down using the HTML SCRIPT tag, as follows...
<TITLE>My Sonified Page</TITLE>

|
The SCRIPT tag that sources in the "music-object.js" file is highlighted in the above sample code segment.
|
Now that the "music-object.js" file has been sourced into the HTML page, you can create a Music Object instance by adding JavaScript code as follows...
<TITLE>My Sonified Page</TITLE>

|
The code that creates the Music Object instance notePlayer is highlighted in the above sample code segment. Notice that a separate SCRIPT tag has been created to contain this JavaScript code. It is not possible to place this code inside the same SCRIPT tag that sources in the "music-object.js" file. If you were to do this, your code may fail in some browsers.
There is an alternative syntax for creating Music Object instances, where you specify the name of the Music Object instance you wish to create as a string parameter in the call to the Music constructor, as follows...
<TITLE>My Sonified Page</TITLE>

|
Although both of the above approaches are valid, the first approach is the preferred one. You will see this approach used in most sample code examples throughout the documentation. Don't be alarmed, however, if you see the second approach in sonification code that you receive from online discussion forums or from other online Web sonification resources.
The music playback capability of the Music Object API is provided by a player which is implemented in native code - not in JavaScript code. This player comes in the form of a browser add-on component: a plug-in for Netscape browsers and an ActiveX control for Microsoft Internet Explorer. Now, in order for a Music Object instance to be operational and have the ability to play music and audio, a player instance must be created that is linked to the Music Object instance. This is done using one of the various embedding methods that are provided by the Music Object API.
In this example, we will use the stubEmbed instance method to embed the Music Object instance's player, since this method provides us a convenient way to embed a player instance that is correctly set up for playing musical notes. The code is as follows...
<TITLE>My Sonified Page</TITLE>

|
The code that embeds the Music Object instance's player is highlighted in the above sample code segment. The file "stub.rmf" is a special type of RMF file that is silent when it is played, because it contains no musical note data. This allows the file to be continuously playing, without actually playing anything other than the musical notes that are triggered using the note playing methods of the Music Object API.
|
Now that your code is sourcing in the "music-object.js" file, creating a Music Object instance, and embedding the Music Object instance's player, your instance should be ready for action and you can now add some code to the page to test that the Music Object instance is operational. For illustration, we will add some code to play musical notes when the user mouses over links.
<TITLE>My Sonified Page</TITLE>

Some Link 1

Some Link 2

Some Link 3

|
The code that has been added for creating links with mouseover sounds is highlighted in the above sample code segment. You will notice that the A tag for each link contains an ONMOUSEOVER attribute. This attribute is used to specify JavaScript code that should be executed when the user mouses over a link. In this example, the code specified in the ONMOUSEOVER attribute is a call to the playNote method of the notePlayer Music Object instance.
The example is now complete. You can use this very basic example as a template for creating other sonified pages, or just as a reference when adding sonification to existing HTML pages.
The above example assumed that the "music-object.js" file was copied into the Web site's folder at the same level as the sonified HTML page. You could alternatively put the "music-object.js" file into a dedicated "javascript" folder. This can be a good practice when you start using some of the many Music Object extensions in order to further enhance the sonification of your Web pages. Each Music Object extension is implemented in its own separate JavaScript file, and placing all the JavaScript files in a dedicated folder can help to better organize the media used by your Web site.
If you decide to place all JavaScript files into a dedicated "javascript" folder, then you must make sure to source in the files using the correct path to the files (including specifying the folder that the files are in). So, in the above example, the SCRIPT tag that sourced in the "music-object.js" file would have to be modified to...

|
The above example assumed that the "stub.rmf" file was copied into the Web site's folder at the same level as the sonified HTML page. You could alternatively put the "stub.rmf" file into a dedicated "music" folder. This can be a good practice when you start using lots of different music files in the sonification of your Web pages. Placing all the music files in a dedicated folder can help to better organize the media used by your Web site.
If you decide to place all music files into a dedicated "music" folder, then you must make sure to specify the correct path to the files (including specifying the folder that the files are in) when making calls to the embedding methods of the Music Object API. So, in the above example, the stubEmbed method call that embedded the Music Object instance's player would have to be modified to...
notePlayer.stubEmbed ('music/stub.rmf');
|
Before you upload your sonified Web pages to test them online, you should make sure that your Web server has the correct MIME type set up for JavaScript files. JavaScript files should always have the file extension ".js" and this file extension should be mapped to the MIME type "application/x-javascript". If you do not have this MIME type configured on your server, your sonified pages may not work correctly in certain browsers. They may work locally while you are authoring and previewing them, but they may not work when visitors try to view them from your Web site. Refer to Dealing with MIME Types for further information.
| Creating Multiple Instances |
It is only possible to play one file at a time through a player instance. So, for example, it is not possible to fade one piece of music out while another piece fades in, using just one player instance. In order to achieve this effect, one would need to use two different player instances, with one playing the file that is fading out and the other playing the file that is fading in. To understand this, it is best to think of the Beatnik Player as though it were a typical CD player in a home stereo system. In order to put a new CD in, it is necessary to take the currently playing CD out first. You can't fade between the two CD's using just one CD player.
Now, it is possible to have an almost unlimited number of player instances on any HTML page, with as many as 16 players actually playing music at any given time. So, by adding a little bit of scripting wizardry, it should be no problem to use two player instances to achieve a cross-fade effect between two music files. And, when you start using 2 or more instances you can really start to do some sophisticated sonification.
Because player instances need to be embedded into the HTML page, it is not possible to dynamically add more player instances after the page has already loaded. So, you need to assess upfront how many instances you might need for your page sonification and then create that many instances. It is possible to embed as many player instances as you want, with some instances that are not doing anything initially and are just "waiting in the wings". Creating multiple instances is quite easy, and just extends on the principles that were demonstrated in the previous section Starting to use Music Object.
In the example below, we are creating two instances: one instance will play musical notes to sonify navigation links, and the other instance will play music in the background...
| |
<TITLE>Multiple Instances Template</TITLE>     Some Link 1
  Some Link 2
  Some Link 3
   |
The text that is highlighted in the above source code listing represents the code that deals specifically with creating multiple instances (two in this example). Of course, there's nothing to say that you couldn't use 3, 4, or even more instances for your page sonification, depending on how complex the sonification is to be. The general rule to remember is that for each Music Object instance you create, you should also embed a corresponding player instance using one of the embedding methods provided by the Music Object API.
| Methods and Properties |
The Music Object API can be broken down into four main functional categories: instance methods, instance properties, static methods, and static properties. The diagram below roughly illustrates the relationship between these functional categories.
In the above diagram, the top container represents the Music Object class, which contains the static methods and static properties that are global to any HTML page that is authored using the Music Object API. Static methods and static properties are referenced from the Music object, as in the statement
Below the Music Object container, several containers represent multiple Music Object instances that have been created. Each instance maintains its own state, and this state can be accessed using the instance methods and instance properties. Instance methods and instance properties are referenced from the Music Object instance name. For example, if an instance was created named "myMusicObject", then the statement
Now, let's take a look at each functional category in further detail...
For a full list of all the instance methods, see the Instance Methods reference section.
Instance properties are specific to Music Object instances, as opposed to the shared global audio engine. Each Music Object instance maintains its own state, so the statement
For a full list of all the instance properties, see the Instance Properties reference section.
For a full list of all the static methods, see the Static Methods reference section.
For a full list of all the static properties, see the Static Properties reference section.
| File Types and Functionality |
Beyond the methods that allow control over general Music Object instance state, the core Music Object API offers a healthy share of methods that facilitate playback control and obtaining state information for a Music Object instance's currently loaded file. The Music Object API offers only one set of methods and properties, regardless of the type of file that is currently loaded into an instance. Because the Beatnik Player is capable of playing several audio and music file formats - including RMF, MIDI, WAV, AIFF, and AU - there can be situations where a certain method or property will have no meaning for the file that is currently loaded into the player. For example, if the player had a WAV file loaded, then calling the setProgram method would not be appropriate, since this method only has meaning for RMF and MIDI files.
When a particular method has no meaning for the file type that is loaded into the player, then calling that method will simply not do anything - it will not produce a JavaScript error. If it is a method that returns state about the instance, and the method has no meaning for the file type that is loaded into the player, then the method will return meaningless data. An example of this would be calling the getProgram method for a Music Object instance that had an AIFF file loaded. It is up to you, as a content author, to design your sonification code to be aware of the types of files that are loaded into Music Object instances and to only call methods that are appropriate to those media types.
There are three categories of file types that the Music Object API addresses...
To understand how the playback control API features are broken up into different groups based upon file type, consider the table below. In this table, it is shown that the API provided for the control of RMF file playback is a superset of the API provided for the control of MIDI file playback, and the API provided for the control of MIDI file playback is a superset of the API provided for the control of linear digital audio file playback (WAV, AIFF, AU).
| Music Object API Reserved Words |
To avoid conflicts in your code and possible unexplained failings in your programming, you should be mindful of the reserved words that are defined in the Music Object API. You should avoid using these reserved words, since any variables or functions that you name the same as identifier names that are defined in the Music Object API will likely cause havoc.
The majority of functions and variable names in the Music Object API are prefixed with "mo_", while a few are prefixed with "Music_". This dramatically reduces the likelihood that Music Object identifier names could encroach on your own identifier names. To be safe, always ensure that your sonification code does not define identifiers that begin with "mo_" or "Music_", unless you are specifically writing Music Object extensions.
In addition, the names "Music" and "musicObject" are reserved for the object constructor that lets you define new Music Object instances. You should, of course, never use these names for your own variables or functions, or you will not be able to use the Music Object API at all.
| Layers of the Music Object API |
The Music Object API is made up of several layers, much like the layers of an onion. At the core are the foundation layers upon which all the layers moving outwards are built. Typically, each new layer that is added builds upon previous layers and adds new capabilities. The diagram below illustrates how all the various Music Object layers relate to each other...
The full Music Object API is made up of the following layers, which are discussed in more detail further below...
The core Music Object API, which is implemented in the "music-object.js" JavaScript file, is typically all that is needed in most sonification jobs. None of the further layers are required, but may be used optionally depending on the needs of a sonification job.
The core Music Object API is comprised of three core components, which are available also in the form of separate JavaScript files. Each core component provides a certain subset of the capabilities of the core Music Object API ("music-object.js"), so when using the separate core component JavaScript files, the core components may be combined together in different combinations, depending on the needs of the sonification job at hand. When all three core components are sourced into a page as separate JavaScript files, this has the same effect as sourcing in the standard "music-object.js" file.
So, in other words, the following code...
   |
...has the same effect as just...
 |
Dividing the core Music Object API into logical core components provides authors with a way to potentially reduce the load time of sonified pages. For instance, if a particular sonified Web site was only targeted to an audience that already had the Beatnik Player installed, or if a gateway page for the site ensured that all those who entered already had the Player installed, then using the compatibility core component in sonified pages of the site would be unnecessary. So, one could then use only the basic and advanced core components. For convenience, core components can also be combined together into a Music Object Suite, as per the specific needs of any given sonification job.
For more information and for guidelines on using the core components, see the section Music Object Core Components.
The optional language modules allow you to customize the prompts that pop up as a result of the user not having the Beatnik Player installed, so that they appear in a language appropriate to the Web content you are sonifying. This applies also to the prompts that appear when the sonified content requires a version of the Beatnik Player higher than the Player that is installed on the user's system, and also the prompt that appears for Netscape Navigator users who have Java disabled.
Using a language module is easy. Simply source in the desired language module's JavaScript file after sourcing in the core Music Object API, as follows...

|
For more information and for guidelines on using language modules, see the section Music Object Language Modules.
Optional extensions allow you to add further capabilities to the Music Object API, and are available as JavaScript files. Different extensions are geared towards different types of sonification needs. For example, "Music Object Extension - Groups" is ideal for making remix interfaces easier to code, and "Music Object Extension - Dynamic" is ideal for making sonified Web pages remain fresh and entertaining.
Extensions offer several key benefits...
Using extensions is easy. Simply source in the desired extensions' JavaScript files after sourcing in the core Music Object API. In the following example, "Music Object Extension - Groups" and "Music Object Extension - Fades" are being used...

|
For more information and for guidelines on using extensions, see the section Music Object Extensions.
Unlike extensions, the optional patches do not add new features or capabilities to the Music Object API, but are intended to fix certain problems that may arise from browser compatibility issues or changes that occur between different versions of the Music Object API. For example, Music Object Patch - Pre 3.3.0 is designed to help authors transition from Music Object version 3.2.x to version 3.3.0 without having to change any sonification scripting, even though changes were made to the API between version 3.2.x and version 3.3.0.
Patches offer several key benefits...
Using patches is easy. Simply source in the desired patches' JavaScript files after sourcing in the core Music Object API. In the following example, "Music Object Patch - Navigator 4.04 Bug" is being used...

|
For more information and for guidelines on using patches, see the section Music Object Patches.
| Making a Custom Music Object Suite |
If you find that certain Music Object extensions or patches are of great value to you in your general sonification, or even just to a specific site you're working on, you may elect to create a custom Music Object suite so that you're not sourcing in several JavaScript files on every sonified Web page. There are benefits to creating a custom Music Object suite, and there are also inherent risks...
|
Creating your own custom Music Object suite is quite easy. You should decide which extensions and patch modules you would like to include in the suite and then simply copy-and-paste these modules into a newly created text file, using your text editor of choice. Be sure to paste the contents of the "music-object.js" file at the top of this document, with all the extension and patch modules pasted in below. You should apply the same principles of ordering as you would when sourcing in the extension and patch modules as discrete JavaScript files.
To be 100% certain of the order in which extensions and patches should be pasted in, consult the documentation for the extensions or patches you plan to use to find out what their dependencies are. As a simple rule, if an extension / patch depends on another extension / patch, then that required extension / patch should be pasted into the suite before the extension / patch that depends on it.


{{>header}} {{#if user}}
Below is your profile information!
Username: {{user.username}}
Avatar:
Sign in and view your profile!
Sign in!


Industry leading open source platform for cloud server and desktop virtualization
Add a Server
Purchase Support
Try Desktop Virtualization


What resources do I have to recycle near me?
{% endif %} {% if info.day is equalto 2 %}Recycling isn’t just tossing your soda bottle into a recycling can.
It’s actively using reusable resources, too, such as: reusable water bottles or grocery bags. Do you have more creative ideas for every day reusable resources? Share them with us using #recyclatory!
{% endif %} {% if info.day is equalto 3 %}What’s recyclable?
According to Waste Management, there are many things beyond plastic and paper that you can recycle. When was the last time you recycled any metals, cardboard, glass, batteries, bulbs and electronics?
{% endif %} {% if info.day is equalto 4 %}Metals
According to Waste Management, cans (aluminum, steel and tin) and aluminum foil and bakeware can all be recycled. Next time you crack open a can of your favorite energy drink or soda, be sure to remember it can be recycled.
{% endif %} {% if info.day is equalto 5 %}Cardboard
According to Waste Management, there are a lot of categories of paper that need recycling that we don’t often remember. \ Do you recognize any of these frequently thrown away items?
scroll down to see how you better our planet
You’ve hit your first milestone! Don’t stop now. Do something — recycle.
{% endif %} {% if info.day is equalto 7 %}Glass
There are three basic types of glass: flint, amber and emerald. No matter what type of glass it is, before it’s recycled, it must be broken down into smaller pieces. For this reason, you shouldn’t place mixed colors of glass into your recycling bin. Once it’s mixed up, there’s no easy method of organization again.
{% endif %} {% if info.day is equalto 8 %}Batteries
If you don’t recycle batteries because it’s more complicated than rolling a bin to the street, then maybe rechargeable batteries would be worth the investment.
{% endif %} {% if info.day is equalto 9 %}Bulbs
“If every home in America replaced just one incandescent light bulb with an ENERGY STAR qualified CFL, in one year it would save enough energy to light more than 3 million homes,” according to Energy Star’s U.S. government webpage. “That would prevent the release of greenhouse gas emissions equal to that of about 800,000 cars.”
{% endif %} {% if info.day is equalto 10 %}Electronics
Did you know that you can recycle many household appliances and electronics? You can! Your old laptops, keyboards, printers, televisions, stereos and cell phones are all up for recycling business grabs.
{% endif %}scroll down to see how you better our planet
Can you believe you’ve reached the halfway point of a new lifetime habit of recycling?
Don’t stop now. Do something — recycle.
Don’t forget to share your success with friends on social media.
{% endif %} {% if info.day is equalto 12 %}Where does my recycling go? Are there factories in the U.S.?
Watch this video to find out.
{% endif %} {% if info.day is equalto 13 %}How much waste is actually recycled?
Out of all of our waste America only recycles about a third of it. This might not sound too bad, but Mother Nature Network puts it into perspective for us.
“That's not bad, considering less than 7 percent of the country's trash was recycled in 1960, and nearly 94 percent of it wound up in landfills. But since that 94 percent totaled only 82.5 million tons, and today's 54 percent totals 132 million tons, it's clear the job is far from finished.”{% endif %} {% if info.day is equalto 14 %}
How much waste is actually recycled?
“Recycling one aluminum can saves enough energy to listen to a full album on your iPod,”
according to DoSomething.org. “Recycling 100 cans could light your bedroom for two whole weeks.”
{% endif %} {% if info.day is equalto 15 %}Zero Waste Town
What if you could eliminate waste, as a whole? Would you do it? That’s what this town in Japan did.
{% endif %}scroll down to see how you better our planet
You’re three quarters of the way to saving the world!
And in the recycling world, 75 cents is a lot. Was that a cheap joke? But seriously, don’t stop now. Do something — recycle.
{% endif %} {% if info.day is equalto 17 %}Resources
We’d like to introduce you to some pretty cool friends. These are a few non-profit organizations who focus on recycling and improving our world!
{% endif %} {% if info.day is equalto 18 %}Economic impact of recycling
In 2015, the U.S. conducted a economic impact study on the scrap recycling industry. It found that in North Carolina alone, the industry created 4,881 direct jobs. What to know what the report meant for your state? Check it out here.
{% endif %} {% if info.day is equalto 19 %}Green Business
Are you a business owner or entrepreneur? Your company can be part of the solution. Find out how to become a green business here.
{% endif %} {% if info.day is equalto 20 %}See what our friends at the Natural Resources Defense Council have to say.
{% endif %}


LEAGUE OF GENTLEMEN, THE (director: Basil Dearden; screenwriter: John Boland (novel)/Bryan Forbes; cinematographer: Arthur Ibbetson; editor: John D. Guthridge; cast: Jack Hawkins (John George Norman Hyde (Lt. Col.)), Nigel Patrick (Peter Graham Race (Transport Major)), Roger Livesey ('Padre' Mycroft (Quartermaster Capt.)), Richard Attenborough (Edward Lexy (Radio Lt.)), Bryan Forbes (Martin Porthill (Capt.)), Kieron Moore (Stevens (Capt.)), Robert Coote (Bunny Warren), Terence Alexander (Rupert Rutland-Smith (Major)), Norman Bird (Frank Weaver (Explosives Capt.)), 1959-UK)
Reviewed by Dennis Schwartz
The League of Gentlemen is a fine example of old-fashioned English humor: droll and civil. Jack Hawkins is the brusque, control-freak, ex-British army colonel during WW11 who has read the American novel The Golden Fleece, which gives him the bright idea that he can rob a bank with some ex-military personnel as experts. He is embittered that he was forced out of the service after twenty-five years. He thereby plans this spiteful caper, as he carefully chooses a seven-man team of similarly discontented military men, but unlike him, those with checkered criminal pasts in the service who were cashiered out. He gets them to a meeting where he treats them to an expensive lunch and tells them his plans to rob a bank for a million dollars; they are then told that they will all have equal shares.
The film's strong suit is watching the precision planning that goes into the operation as it unfolds and how all these older blokes exhibit their odd personalties to mesh into a team-operation replete with proper military decorum. Because of their untenable civilian situations, all seven show why it is likely they would participate in this operation.
Nigel Patrick is the ex-major, always a schemer, involved in black market activities in Berlin but also proud to be known as a survivor of Dunkirk. He has fallen on hard times and has lost all his money in a card game. He takes over as second-in-command for this caper. Roger Livesey got bounced from the service for indecent exposure and has now made a career of disguising himself as a religious man, his latest being as a padre. Richard Attenborough is an expert radio operator who now rigs slot machines for the casino owners. He was kicked out of the military because he sold secrets to the Russians for the money not because he shared their ideals. Norman Bird is an explosive expert who got drunk on his watch and four men under him died because of his negligence in a bomb-disposal operation. He is unhappily shown as a henpecked husband in civilian life. Kieron Moore is an ex-fascist who joined the army but was the odd man out in a criminal investigation and is having money problems currently working as a masseur. Bryan Forbes lives off middle-aged women and is finding his current life unbearably confusing. Terence Alexander is a pianist who has not fared well in peacetime England.
It is determined by Hawkins that they need military supplies for their caper, so they impersonate high-ranking army officers and pull a surprise inspection on an army base, while some of them cut the radio wires and show up to do repairs but instead steal gas masks and other supplies they need for their job. They cleverly speak with Irish accents so that the IRA gets blamed.
The methodical job is pulled off with success, as in the midst of tear gas they explode the criminals don their gas masks and walk off with the loot. As they meet in Hawkins' house to divide the loot and celebrate their good fortunes, a surprise ending takes place.
A very watchable caper movie, but with a decided British edge to it which might inhibit some American viewers from enjoying it as much. The lovable rogue characters give the film a spirited uplift, with Hawkins, Patrick, Livesey, and Attenborough being particularly good in their portrayals. What the film lacks is any kind of intensity, it's all comedy and manners.
REVIEWED ON 5/19/2000 GRADE: C+
Dennis Schwartz: "Ozus' World Movie Reviews"
http://www.sover.net/~ozus
<EMAIL_ADDRESS>© ALL RIGHTS RESERVED DENNIS SCHWARTZ
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


| Please activate your Pornhub account. |
|
Hello ihadtopee, Your Pornhub account ihadtopee has been successfully created. Now, click the button below to activate and get started! If the button doesn’t work, copy and paste this link into your browser: http://www.pornhub.com/user/confirm?id=6579171&code=013042be38a3f91 Pornhub is not just a video tube site, we consider ourselves a community. We want our members to be able to connect with each other at all times. If you received this email in error and did not sign up for a Pornhub account you can simply ignore this email |


The Falcon III Radio is a tactical radio developed by Harris Corp. The Falcon III supports many different waveforms for communication. I tested the radio based on guided tests; when bugs were found, I tracked, debugged, and fixed them. The Falcon III runs on an embedded Linux-based OS, and most of the code I worked with was DSP, digital signal processor, code written in C or C++. (Click images below to enlarge)


abstract
Methods overridden from java.lang.Object are not reported by this inspection.
java.lang.Object


/*
* FlashPlugin
* Visit http://createjs.com/ for documentation, updates and examples.
*
*
* Copyright (c) 2012 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @module SoundJS
*/
// namespace:
this.createjs = this.createjs || {};
(function () {
/**
* Play sounds using a Flash instance. This plugin is not used by default, and must be registered manually in
* {{#crossLink "Sound"}}{{/crossLink}} using the {{#crossLink "Sound/registerPlugins"}}{{/crossLink}} method. This
* plugin is recommended to be included if sound support is required in older browsers such as IE8.
*
* This plugin requires FlashAudioPlugin.swf and swfObject.js (which is compiled
* into the minified FlashPlugin-X.X.X.min.js file. You must ensure that FlashPlugin.BASE_PATH is
* set when using this plugin, so that the script can find the swf.
*
*
Example

* createjs.FlashPlugin.BASE_PATH = "../src/SoundJS/";
* createjs.Sound.registerPlugins([createjs.WebAudioPlugin, createjs.HTMLAudioPlugin, createjs.FlashPlugin]);
* // Adds FlashPlugin as a fallback if WebAudio and HTMLAudio do not work.
*
* Note that the SWF is embedded into a container DIV (with an id and classname of "SoundJSFlashContainer"), and
* will have an id of "flashAudioContainer". The container DIV is positioned 1 pixel off-screen to the left to avoid
* showing the 1x1 pixel white square.
*
*
Known Browser and OS issues for HTML Audio

* All browsers

*

 There can be a delay in flash player starting playback of audio. This has been most noticeable in Firefox.
* Unfortunely this is an issue with the flash player and therefore cannot be addressed by SoundJS.

*
* @class FlashPlugin
* @constructor
*/
function FlashPlugin() {
this.init();
}
var s = FlashPlugin;
/**
* The capabilities of the plugin. This is generated via the {{#crossLink "WebAudioPlugin/generateCapabilities"}}{{/crossLink}}
* method. Please see the Sound {{#crossLink "Sound/getCapabilities"}}{{/crossLink}} method for a list of available
* capabilities.
* @property capabilities
* @type {Object}
* @static
*/
s.capabilities = null;
/**
* The path relative to the HTML page that the FlashAudioPlugin.swf resides. Note if this is not correct, this
* plugin will not work.
* @property BASE_PATH
* @type {String}
* @default src/SoundJS
* @static
*/
s.BASE_PATH = "src/SoundJS/";
/**
* Determine if the plugin can be used in the current browser/OS.
* @method isSupported
* @return {Boolean} If the plugin can be initialized.
* @static
*/
s.isSupported = function () {
if (createjs.Sound.BrowserDetect.isIOS) {
return false;
}
s.generateCapabilities();
if (swfobject == null) {
return false;
}
return swfobject.hasFlashPlayerVersion("9.0.0");
//TODO: Internal detection instead of SWFObject?
};
/**
* Determine the capabilities of the plugin. Used internally. Please see the Sound API {{#crossLink "Sound/getCapabilities"}}{{/crossLink}}
* method for an overview of plugin capabilities.
* @method generateCapabiities
* @static
* @protected
*/
s.generateCapabilities = function () {
if (s.capabilities != null) {
return;
}
// TODO change to support file types using SUPPORTED_EXTENSIONS like other plugins if possible
// see http://helpx.adobe.com/flash/kb/supported-codecs-flash-player.html
var c = s.capabilities = {
panning:true,
volume:true,
tracks:-1,
mp3:true,
ogg:false,
mpeg:true,
wav:true,
m4a:true,
mp4:true,
aiff:false, // not listed in player but is Supported by Flash so this may be true
wma:false,
mid:false
};
};
var p = s.prototype = {
/**
* An object hash indexed by ID that indicates if each source is loaded or loading.
* @property audioSources
* @type {Object}
* @protected
*/
audioSources:null,
/**
* The internal volume value of the plugin.
* @property volume
* @type {Number}
* @default 1
* @protected
*/
volume:1,
/**
* The id name of the DIV that gets created for Flash content.
* @property CONTAINER_ID
* @type {String}
* @default flashAudioContainer
* @protected
*/
CONTAINER_ID:"flashAudioContainer",
/**
* The id name of the DIV wrapper that contains the Flash content.
* @property WRAPPER_ID
* @type {String}
* @default SoundJSFlashContainer
* @protected
* @since 0.4.1
*/
WRAPPER_ID:"SoundJSFlashContainer",
// doc'd above
capabilities:null,
// FlashPlugin Specifics
/**
* A reference to the DIV container that gets created to hold the Flash instance.
* @property container
* @type {HTMLDivElement}
* @protected
*/
container:null,
/**
* A reference to the Flash instance that gets created.
* @property flash
* @type {Object | Embed}
* @protected
*/
flash:null,
/**
* Determines if the Flash object has been created and initialized. This is required to make ExternalInterface
* calls from JavaScript to Flash.
* @property flashReady
* @type {Boolean}
* @default false
*/
flashReady:false,
/**
* A hash of SoundInstances indexed by the related ID in Flash. This lookup is required to connect sounds in
* JavaScript to their respective instances in Flash.
* @property flashInstances
* @type {Object}
* @protected
*/
flashInstances:null,
/**
* A hash of Sound Preload instances indexed by the related ID in Flash. This lookup is required to connect
* a preloading sound in Flash with its respective instance in JavaScript.
* @property flashPreloadInstances
* @type {Object}
* @protected
*/
flashPreloadInstances:null,
/**
* A hash of Sound Preload instances indexed by the src. This lookup is required to load sounds if internal
* preloading is tried when flash is not ready.
* @property preloadInstances
* @type {Object}
* @protected
* @since 0.4.0
*/
preloadInstances:null,
/**
* An array of Sound Preload instances that are waiting to preload. Once Flash is initialized, the queued
* instances are preloaded.
* @property queuedInstances
* @type {Object}
* @protected
*/
queuedInstances:null,
/**
* A developer flag to output all flash events to the console (if it exists). Used for debugging.
*
* createjs.Sound.activePlugin.showOutput = true;
*
* @property showOutput
* @type {Boolean}
* @default false
*/
showOutput:false,
/**
* An initialization function run by the constructor
* @method init
* @protected
*/
init:function () {
this.capabilities = s.capabilities;
this.audioSources = {};
this.flashInstances = {};
this.flashPreloadInstances = {};
this.preloadInstances = {};
this.queuedInstances = [];
// Create DIV
var w = this.wrapper = document.createElement("div");
w.id = this.WRAPPER_ID;
w.style.position = "absolute";
w.style.marginLeft = "-1px";
w.className = this.WRAPPER_ID;
document.body.appendChild(w);
// Create Placeholder
var c = this.container = document.createElement("div");
c.id = this.CONTAINER_ID;
c.appendChild(document.createTextNode("SoundJS Flash Container"));
w.appendChild(c);
// Embed SWF
var val = swfobject.embedSWF(s.BASE_PATH + "FlashAudioPlugin.swf", this.CONTAINER_ID, "1", "1",
"9.0.0", null, null, null, null,
createjs.proxy(this.handleSWFReady, this)
);
//TODO: Internal detection instead of swfobject
},
/**
* The SWF used for sound preloading and playback has been initialized.
* @method handleSWFReady
* @param {Object} event Contains a reference to the swf.
* @protected
*/
handleSWFReady:function (event) {
this.flash = event.ref;
this.loadTimeout = setTimeout(createjs.proxy(this.handleTimeout, this), 2000); // OJR note this function doesn't do anything right now
},
/**
* The Flash application that handles preloading and playback is ready. We wait for a callback from Flash to
* ensure that everything is in place before playback begins.
* @method handleFlashReady
* @protected
*/
handleFlashReady:function () {
this.flashReady = true;
// Anything that needed to be preloaded, can now do so.
for (var i = 0, l = this.queuedInstances.length; i < l; i++) {
this.flash.register(this.queuedInstances[i]); // NOTE this flash function currently does nothing
}
this.queuedInstances.length = 0;
// Associate flash instance with any preloadInstance that already exists.
for (var n in this.flashPreloadInstances) {
this.flashPreloadInstances[n].initialize(this.flash);
}
// load sounds that tried to preload before flash was ready
for (var n in this.preloadInstances) {
this.preloadInstances[n].initialize(this.flash);
}
this.preloadInstances = {};
// Associate flash instance with any sound instance that has already been played.
for (var n in this.flashInstances) {
this.flashInstances[n].initialize(this.flash);
}
},
/**
* The callback when Flash does not initialize. This usually means the SWF is missing or incorrectly pathed.
* @method handleTimeout
* @protected
*/
handleTimeout:function () {
//LM: Surface to user? AUDIO_FLASH_FAILED
},
/**
* Pre-register a sound instance when preloading/setup. Note that the FlashPlugin will return a SoundLoader
* instance for preloading since Flash can not access the browser cache consistently.
* @method register
* @param {String} src The source of the audio
* @param {Number} instances The number of concurrently playing instances to allow for the channel at any time.
* @return {Object} A result object, containing a tag for preloading purposes.
*/
register:function (src, instances) {
//Note that currently, registering with the flash instance does nothing.
this.audioSources[src] = true; // NOTE this does not mean preloading has started
if (!this.flashReady) {
this.queuedInstances.push(src);
} else {
this.flash.register(src); // NOTE this flash function currently does nothing // OJR remove this entire thing, as it does nothing?
}
var tag = new SoundLoader(src, this, this.flash);
return {
tag:tag
};
},
/**
* Remove a sound added using {{#crossLink "FlashPlugin/register"}}{{/crossLink}}. Note this does not cancel a
* preload.
* @method removeSound
* @param {String} src The sound URI to unload.
* @since 0.4.1
*/
removeSound:function (src) {
delete(this.audioSources[src]);
var i = this.queuedInstances.indexOf(src);
if(i != -1) {
this.queuedInstances.splice(i,1);
}
// NOTE sound cannot be removed from a swf
},
/**
* Remove all sounds added using {{#crossLink "FlashPlugin/register"}}{{/crossLink}}. Note this does not cancel a preload.
* @method removeAllSounds
* @param {String} src The sound URI to unload.
* @since 0.4.1
*/
removeAllSounds:function () {
this.audioSources = {}; // this drops all references, in theory freeing them for garbage collection
this.queuedInstances.length = 0;
// OJR these may not be necessary, but are included for cleanup clarity.
this.flashInstances = {};
this.flashPreloadInstances = {};
this.preloadInstances = {};
// NOTE sound cannot be removed from a swf
},
/**
* Create a sound instance. If the sound has not been preloaded, it is internally preloaded here.
* @method create
* @param {String} src The sound source to use.
* @return {SoundInstance} A sound instance for playback and control.
*/
create:function (src) {
if (!this.isPreloadStarted(src)) {
this.preload(src);
}
try {
var instance = new SoundInstance(src, this, this.flash);
return instance;
} catch (err) {
//console.log("Error: Please ensure you have permission to play audio from this location.", err);
}
return null;
},
/**
* Checks if preloading has started for a specific source. If the source is found, we can assume it is loading,
* or has already finished loading.
* @method isPreloadStarted
* @param {String} src The sound URI to check.
* @return {Boolean}
*/
isPreloadStarted:function (src) {
return (this.audioSources[src] != null);
},
/**
* Preload a sound instance. This plugin uses Flash to preload and play all sounds.
* @method preload
* @param {String} src The path to the Sound
* @param {Object} instance Not used in this plugin.
*/
preload:function (src, instance) {
this.audioSources[src] = true; // NOTE this does not mean preloading has started, just that it will
var loader = new SoundLoader(src, this, this.flash);
loader.load(); // this will handle if flash is not ready
},
/**
* Set the master volume of the plugin, which affects all SoundInstances.
* @method setVolume
* @param {Number} value The volume to set, between 0 and 1.
* @return {Boolean} If the plugin processes the setVolume call (true). The Sound class will affect all the
* instances manually otherwise.
* @since 0.4.0
*/
setVolume:function (value) {
this.volume = value;
return this.updateVolume();
},
/**
* Internal function used to set the gain value for master audio. Should not be called externally.
* @method updateVolume
* @return {Boolean}
* @protected
* @since 0.4.0
*/
updateVolume:function () {
var newVolume = createjs.Sound.masterMute ? 0 : this.volume;
return this.flash.setMasterVolume(newVolume);
},
/**
* Get the master volume of the plugin, which affects all SoundInstances.
* @method getVolume
* @return The volume level, between 0 and 1.
* @since 0.4.0
*/
getVolume:function () {
return this.volume;
},
/**
* Mute all sounds via the plugin.
* @method setMute
* @param {Boolean} value If all sound should be muted or not. Note that plugin-level muting just looks up
* the mute value of Sound {{#crossLink "Sound/getMute"}}{{/crossLink}}, so this property is not used here.
* @return {Boolean} If the mute call succeeds.
* @since 0.4.0
*/
setMute:function (isMuted) {
return this.updateVolume();
},
// Flash Communication
/**
* Used to couple a Flash loader instance with a SoundLoader instance
* @method registerPreloadInstance
* @param {String} flashId Used to identify the SoundLoader.
* @param {SoundLoader} instance The actual instance.
*/
registerPreloadInstance:function (flashId, instance) {
this.flashPreloadInstances[flashId] = instance;
},
/**
* Used to decouple a SoundLoader instance from Flash.
* @method unregisterPreloadInstance
* @param {String} flashId Used to identify the SoundLoader.
*/
unregisterPreloadInstance:function (flashId) {
delete this.flashPreloadInstances[flashId];
},
/**
* Used to couple a Flash sound instance with a {{#crossLink "SoundInstance"}}{{/crossLink}}.
* @method registerSoundInstance
* @param {String} flashId Used to identify the SoundInstance.
* @param {SoundLoader} instance The actual instance.
*/
registerSoundInstance:function (flashId, instance) {
this.flashInstances[flashId] = instance;
},
/**
* Used to decouple a {{#crossLink "SoundInstance"}}{{/crossLink}} from Flash.
* instance.
* @method unregisterSoundInstance
* @param {String} flashId Used to identify the SoundInstance.
* @param {SoundLoader} instance The actual instance.
*/
unregisterSoundInstance:function (flashId) {
delete this.flashInstances[flashId];
},
/**
* Used to output traces from Flash to the console, if {{#crossLink "FlashPlugin/showOutput"}}{{/crossLink}} is
* true.
* @method flashLog
* @param {String} data The information to be output.
*/
flashLog:function (data) {
try {
this.showOutput && console.log(data);
} catch (error) {
}
},
/**
* Handles events from Flash, and routes communication to a {{#crossLink "SoundInstance"}}{{/crossLink}} via
* the Flash ID. The method and arguments from Flash are run directly on the sound instance.
* @method handleSoundEvent
* @param {String} flashId Used to identify the SoundInstance.
* @param {String} method Indicates the method to run.
*/
handleSoundEvent:function (flashId, method) {
var instance = this.flashInstances[flashId];
if (instance == null) {
return;
}
var args = [];
for (var i = 2, l = arguments.length; i < l; i++) {
args.push(arguments[i]);
}
try {
if (args.length == 0) {
instance[method]();
} else {
instance[method].apply(instance, args);
}
} catch (error) {
}
},
/**
* Handles events from Flash and routes communication to a SoundLoader via the Flash ID. The method
* and arguments from Flash are run directly on the sound loader.
* @method handlePreloadEvent
* @param {String} flashId Used to identify the loader instance.
* @param {String} method Indicates the method to run.
*/
handlePreloadEvent:function (flashId, method) {
var instance = this.flashPreloadInstances[flashId];
if (instance == null) {
return;
}
var args = [];
for (var i = 2, l = arguments.length; i < l; i++) {
args.push(arguments[i]);
}
try {
if (args.length == 0) {
instance[method]();
} else {
instance[method].apply(instance, args);
}
} catch (error) {
}
},
/**
* Handles events from Flash intended for the FlashPlugin class. Currently only a "ready" event is processed.
* @method handleEvent
* @param {String} method Indicates the method to run.
*/
handleEvent:function (method) {
//Sound.log("Handle Event", method);
switch (method) {
case "ready":
clearTimeout(this.loadTimeout);
this.handleFlashReady();
break;
}
},
/**
* Handles error events from Flash. Note this function currently does not process any events.
* @method handleErrorEvent
* @param {String} error Indicates the error.
*/
handleErrorEvent:function (error) {
},
toString:function () {
return "[FlashPlugin]";
}
}
createjs.FlashPlugin = FlashPlugin;
// NOTE documentation for this class can be found online or in WebAudioPlugin.SoundInstance
// NOTE audio control is shuttled to a flash player instance via the flash reference.
function SoundInstance(src, owner, flash) {
this.init(src, owner, flash);
}
var p = SoundInstance.prototype = {
src:null,
uniqueId:-1,
owner:null,
capabilities:null,
flash:null,
flashId:null, // To communicate with Flash
loop:0,
volume:1,
pan:0,
offset:0, // used for setPosition on a stopped instance
duration:0,
delayTimeoutId:null,
muted:false,
paused:false,
// mix-ins:
// EventDispatcher methods:
addEventListener:null,
removeEventListener:null,
removeAllEventListeners:null,
dispatchEvent:null,
hasEventListener:null,
_listeners:null,
// Callbacks
onComplete:null,
onLoop:null,
onReady:null,
onPlayFailed:null,
onPlayInterrupted:null,
onPlaySucceeded:null,
// Constructor
init:function (src, owner, flash) {
this.src = src;
this.owner = owner;
this.flash = flash;
},
initialize:function (flash) {
this.flash = flash;
},
// Public API
interrupt:function () {
this.playState = createjs.Sound.PLAY_INTERRUPTED;
if (this.onPlayInterrupted != null) {
this.onPlayInterrupted(this);
}
this.flash.interrupt(this.flashId);
this.cleanUp();
this.paused = false;
this.sendEvent("interrupted");
},
cleanUp:function () {
clearTimeout(this.delayTimeoutId);
this.owner.unregisterSoundInstance(this.flashId);
createjs.Sound.playFinished(this);
},
play:function (interrupt, delay, offset, loop, volume, pan) {
createjs.Sound.playInstance(this, interrupt, delay, offset, loop, volume, pan);
},
beginPlaying:function (offset, loop, volume, pan) {
this.loop = loop;
this.paused = false;
if (!this.owner.flashReady) {
return false;
}
this.offset = offset;
this.flashId = this.flash.playSound(this.src, offset, loop, volume, pan);
if (this.flashId == null) {
if (this.onPlayFailed != null) {
this.onPlayFailed(this);
}
this.cleanUp();
return false;
}
//this.duration = this.flash.getDuration(this.flashId); // this is 0 at this point
if (this.muted) {
this.setMute(true);
}
this.playState = createjs.Sound.PLAY_SUCCEEDED;
this.owner.registerSoundInstance(this.flashId, this);
this.onPlaySucceeded && this.onPlaySucceeded(this);
this.sendEvent("succeeded");
return true;
},
playFailed:function () {
this.playState = createjs.Sound.PLAY_FAILED;
if (this.onPlayFailed != null) {
this.onPlayFailed(this);
}
this.cleanUp();
this.sendEvent("failed");
},
pause:function () {
if (!this.paused && this.playState == createjs.Sound.PLAY_SUCCEEDED) {
this.paused = true;
clearTimeout(this.delayTimeoutId);
return this.flash.pauseSound(this.flashId);
}
return false;
},
resume:function () {
if (!this.paused) {
return false;
}
this.paused = false;
return this.flash.resumeSound(this.flashId);
},
stop:function () {
this.playState = createjs.Sound.PLAY_FINISHED;
this.paused = false;
this.offset = 0; // flash destroys the wrapper, so we need to track offset on our own
var ok = this.flash.stopSound(this.flashId);
this.cleanUp();
return ok;
},
setVolume:function (value) {
if (Number(value) == null) {
return false;
}
value = Math.max(0, Math.min(1, value));
this.volume = value;
return this.flash.setVolume(this.flashId, value)
},
getVolume:function () {
return this.volume;
},
mute:function (value) {
this.muted = value;
return value ? this.flash.muteSound(this.flashId) : this.flash.unmuteSound(this.flashId);
},
setMute:function (value) {
this.muted = value;
return value ? this.flash.muteSound(this.flashId) : this.flash.unmuteSound(this.flashId);
},
getMute:function () {
return this.muted;
},
getPan:function () {
return this.pan;
},
setPan:function (value) {
this.pan = value;
return this.flash.setPan(this.flashId, value);
},
getPosition:function () {
var value = -1;
if (this.flash && this.flashId) {
value = this.flash.getPosition(this.flashId); // this returns -1 on stopped instance
}
if (value != -1) {
this.offset = value;
}
return this.offset;
},
setPosition:function (value) {
this.offset = value;
this.flash && this.flashId && this.flash.setPosition(this.flashId, value);
return true;
},
getDuration:function () {
var value = -1;
if (this.flash && this.flashId) {
value = this.flash.getDuration(this.flashId);
}
if (value != -1) {
this.duration = value;
}
return this.duration;
},
// Flash callbacks, only exist in FlashPlugin
sendEvent:function (eventString) {
var event = {
target:this,
type:eventString
};
this.dispatchEvent(event);
},
/**
* Called from Flash. Lets us know flash has finished playing a sound.
* #method handleSoundFinished
* @protected
*/
handleSoundFinished:function () {
this.playState = createjs.Sound.PLAY_FINISHED;
this.cleanUp();
if (this.onComplete != null) {
this.onComplete(this);
}
this.sendEvent("complete");
},
/**
* Called from Flash. Lets us know that flash has played a sound to completion and is looping it.
* #method handleSoundLoop
* @protected
*/
handleSoundLoop:function () {
if (this.onLoop != null) {
this.onLoop(this);
}
this.sendEvent("loop");
},
toString:function () {
return "[FlashPlugin SoundInstance]"
}
}
// Note this is for SoundInstance above.
createjs.EventDispatcher.initialize(SoundInstance.prototype);
// do not add SoundInstance to namespace
/**
* SoundLoader provides a mechanism to preload Flash content via PreloadJS or internally. Instances are returned to
* the preloader, and the load method is called when the asset needs to be requested.
*
* SoundLoader has the same APIs as an <audio> tag. The instance calls the onload, onprogress,
* and onerror callbacks when necessary.
*
* #class SoundLoader
* @param {String} src The path to the sound
* @param {Object} flash The flash instance that will do the preloading.
* @protected
*/
function SoundLoader(src, owner, flash) {
this.init(src, owner, flash);
}
var p = SoundLoader.prototype = {
/**
* A reference to the Flash instance that gets created.
* #property flash
* @type {Object | Embed}
*/
flash:null,
/**
* The source file to be loaded.
* #property src
* @type {String}
*/
src:null,
/**
* ID used to facilitate communication with flash.
* #property flashId
* @type {String}
*/
flashId:null,
/**
* The percentage of progress.
* #property progress
* @type {Number}
* @default -1
*/
progress:-1,
/**
* Used to report if audio is ready. Value of 4 indicates ready.
* #property readyState
* @type {Number}
* @default 0
*/
readyState:0,
/**
* Indicates if load has been called on this.
* #property loading
* @type {Boolean}
* @default false
*/
loading:false,
/**
* Plugin that created this. This will be an instance of FlashPlugin.
* #property owner
* @type {Object}
*/
owner:null,
// Calbacks
/**
* The callback that fires when the load completes. This follows HTML tag name conventions.
* #property onload
* @type {Method}
*/
onload:null,
/**
* The callback that fires as the load progresses. This follows HTML tag name conventions.
* #property onprogress
* @type {Method}
*/
onprogress:null,
/**
* The callback that fires if the load hits an error. This follows HTML tag name conventions.
* #property onerror
* @type {Method}
*/
onerror:null,
// constructor
init:function (src, owner, flash) {
this.src = src;
this.owner = owner;
this.flash = flash;
},
/**
* Called when Flash has been initialized. If a load call was made before this, call it now.
* #method initialize
* @param {Object | Embed} flash A reference to the Flash instance.
*/
initialize:function (flash) {
this.flash = flash;
if (this.loading) {
this.loading = false;
this.load(this.src);
}
},
/**
* Start loading.
* #method load
* @param {String} src The path to the sound.
* @return {Boolean} If the load was started. If Flash has not been initialized, the load will fail.
*/
load:function (src) {
if (src != null) {
this.src = src;
}
if (this.flash == null || !this.owner.flashReady) {
this.loading = true;
// register for future preloading
this.owner.preloadInstances[this.src] = this; // OJR this would be better as an API call
return false;
}
this.flashId = this.flash.preload(this.src);
// Associate this preload instance with the FlashID, so callbacks can route here.
this.owner.registerPreloadInstance(this.flashId, this);
return true;
},
/**
* Receive progress from Flash and pass it to callback.
* #method handleProgress
* @param {Number} loaded Amount loaded
* @param {Number} total Total amount to be loaded.
*/
handleProgress:function (loaded, total) {
this.progress = loaded / total;
this.onprogress && this.onprogress({loaded:loaded, total:total, progress:this.progress});
},
/**
* Called from Flash when sound is loaded. Set our ready state and fire callbacks / events
* #method handleComplete
*/
handleComplete:function () {
this.progress = 1;
this.readyState = 4;
createjs.Sound.sendFileLoadEvent(this.src); // fire event or callback on Sound // can't use onload callback because we need to pass the source
this.onload && this.onload();
},
/**
* Receive error event from flash and pass it to callback.
* @param {Event} error
*/
handleError:function (error) {
this.onerror && this.onerror(error);
},
toString:function () {
return "[FlashPlugin SoundLoader]";
}
}
// do not add SoundLoader to namespace
}());