TweetFollow Us on Twitter

Async Sounds
Volume Number:7
Issue Number:3
Column Tag:Pascal Forum

Related Info: Sound Manager

Asynchronous Sounds

By Aaron Walsh, Chestnut Hill, MA

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

[Aaron Walsh works in Information Processing Support (IPS) as a consultant for Boston College. In addition to supporting the college’s computing community, Aaron oversees the Advanced Technology Center (ATC).

The ATC provides faculty and staff with access to technology such as high resolution scanners, large screen color monitors, film recording, and sound digitizing for the vision impared. It also provides for the community help to evaluate some of the industries most advanced personal workstations (ex. IBM RS6000, Apple Macintosh IIFX).]

Introduction

This article will explain how to add sound to your application using the Sound Manager. The Sound Manager replaces the Sound Driver, which was the original device driver for the Macintosh Plus and the Macintosh SE. The Sound Manager is available in System 6.0.x, providing a more flexible and convenient means of using sound on the Macintosh. Complete Sound Manager documentation is available on AppleLink.

I will concentrate on the use of sound resources (resources of type ‘snd ‘) and the Sound Manager calls used to play these resources. Not only is this method simple, but it is also extremely powerful in the sense that you can take ‘snd ‘ resources from other applications and incorporate them into yours. Simply use ResEdit to copy the ‘snd ‘ resource to your application. Once you have the resource, you should be able to play it to your heart’s content.

My program demonstrates the use of asynchronous sound. Playing sound asynchronously allows your application to continue executing while the sound is being generated. If the sound is not played asynchronously (that is, sychronously) the application will wait until the entire sound has finished playing before executing the next statement. This is fine if the sound is short, or you if you do indeed want the sound played before continuing. However, this is next to worthless if you need the sound generated concurrently with graphics or other tasks (can you imagine Crystal Quest seizing each time a Zap, Bong, or Gloink is made?!).

Please note that my code serves as a functional demonstration, not an iron clad application. The only task performed while the sound plays is a flashing menu bar, demonstrating asynchronous sound. Also, error checking is not terribly sophisticated. I give you the necessary framework to build upon, not extra code to wade through. For a fully functional application, complete with robust error checking and loaded with comments, hop on AppleLink. In the sample code section of Macintosh Technical Support is SoundApp. It was written by Jim Reekes, the same Apple employee who wrote the Sound Manager documentation. Not only is this a thorough example of the Sound Manager, but it also contains a good deal of information on known Sound Manager bugs.

On with the show....

Structurally Sound

Before plunging headfirst into a long-winded Sound Manager discussion and code examples, you may find it helpful (perhaps even necessary) to understand the basic elements used in creating sound on the Macintosh. The process of creating sounds is similar to the operation of an assembly line. The sound data is taken through various stages of processing, massaged and tweaked along the way until it reaches its final destination (usually the speaker, in some cases a MIDI device).

Sound resources (resources of type ‘snd ‘, hereafter referred to as snd’s) contain the data to be put on the assembly line. Snd’s can be created from scratch with tools such as ResEdit, at the expense of your sanity. I recommend using a sound digitizer, such as MacRecorder by Farallon. This allows you to record live and prerecorded music directly into an snd resource. Very clean, very easy. You can also edit the sound, adding special effects such as echo, bender, fade, etc., to produce custom sounds and music.

Snd’s come in two formats. Format 1 was developed by Apple, specifically for use with the Sound Manager. Format 2 was also designed by Apple, but for use with HyperCard. The Sound Manager is capable of playing both formats, as my sample code demonstrates. If you do not know what format your snd is, check the first word (in hex format) of the resource with resource tool such as ResEdit. This word contains the snd format (0001 = Format 1, 0002 = Format 2). MacRecorder is capable of creating either format, although saving your sound directly into an snd resource will create format 1.

An ‘snd ‘ resource contains sound commands, special instructions containing information which alter the final sound. A sound command may be nothing more that the description of a note to be played, or it may be an instruction used change the characteristic of a sound already in progress (i.e. amplitude, timber, frequency, etc).

Each sound command is exactly eight bytes in length:

The first word is the command number, followed by six bytes that comprise the sound command options. The pointer bit indicates that the snd contains both sound commands and associated sound data (i.e. sampled sound or wave table data). A full description of available sound commands is included in the Sound Manager documentation.

Although an snd resource contains the needed sound commands to generate synchronous sound, you can drop additional sound commands on the conveyor belt with the SndDoCommand and SndDoImmediate calls. We will call SndDoCommand to add a callback sound command to the process, which will facilitate the generation of asynchronous sound. I’ll explain this in detail later.

The sound commands are held in memory in a structure called a channel. The default sound channel is a queue capable of holding 128 sound commands, which are passed one at time to a specific synthesizer. This sound channel provides interaction between the application and the audio hardware. When you add a sound command as described above, it is actually sent to the same sound channel in memory that holds the snd’s sound commands.

The sound commands are then sent to a synthesizer. A synthesizer is much like a device driver. It is responsible for interpreting the sound commands sent through the sound channel and playing them on the hardware associated with it (usually the speaker).

In short, you take a bunch of sound commands (from an snd resource) and cram them into a sound channel. One at a time they are sent to a synthesizer where they are interpreted and passed on to the speaker which makes the final sound [Figure 1]. Easy, huh? How do you get all this to happen? I thought you might be wondering....

Figure 1.

Tools of the Trade

Now that you know the basic process that occurs when sound is played on the Macintosh, lets explore the Toolbox calls that make it possible.

To produce synchronous sound you only need to use one call:

{1}

Function SndPlay (chan: SndChannelPtr; sndHdl: Handle; async: Boolean) 
: OSErr;

If you pass NIL as the SndChannelPtr parameter, you will only be able to produce synchronous sound (in this case the Boolean parameter is ignored, even if True is passed). If you can at least pass the snd’s handle, you can produce sound:

{2}

Error := SndPlay(NIL, mySndHandle, FALSE);

In this case the sound must finish playing before execution resumes. A default sound channel is created in the application’s heap, through which the sound commands are passed to a synthesizer for processing. After the sound commands have been processed and the sound has finished playing on the audio hardware, the memory used for the default sound channel is freed.

To produce asynchronous sound, you must pass a channel pointer to SndPlay (NIL won’t cut it) along with True as the Boolean parameter. Hmmmm....well, the first thing you need to do is create a sound channel in memory:

{3}

Function SndNewChannel (VAR chan: SndChannelPtr; synth: Integer; init: 
Longint; userRoutine: ProcPtr): OSErr;

Hold it! We only need a channel pointer, so why all the parameters? I thought you might ask.

Turn the Channel, Please

To better understand the SndNewChannel call, we must have a more intimate knowledge of the parameters it requires. Let’s begin with a more thorough explanation of the synthesizer.

On the Macintosh, a synthesizer is actually a resource of type ‘snth’. It is code that interprets the sound commands sent through the channel. Currently, the Sound Manager offers four standard synthesizers, each with special capabilities that provide different methods for expressing sound:

• The note synthesizer is capable of generating simple melodies and sounds. Only one note at a time can be played.

• The wave-table synthesizer produces more complex sounds, based on the description of a single wave cycle. Multipart music is possible using one polyphonic channel or several monophonic channels.

• The MIDI synthesizer allows music to be played on an external synthesizer, provided a Musical Instrument Data Interface (MIDI) adapter is connected to one of the serial ports. Fully functional MIDI applications cannot be written using the current Sound Manager due to bugs and limitations.

• The sampled-sound synthesizer will play back digitally prerecorded or precomputed sounds. The sounds are passed to the synthesizer in sampled sound buffers. These buffers can be played at different sampling rates to effect sound pitch.

Since each ‘snth’ is a resource, a resource ID is used to distinguish between them:

ID Synthesizer Target Macintosh

$0001 noteSynth general for any Macintosh

$0003 waveTableSynth general for any Macintosh

$0005 sampledSynth general for any Macintosh

$0006-$00FF reserved for Apple general for any Macintosh

$0100-$0799 free for Developer general for any Macintosh

$0801 noteSynth Mac w/Apple Sound Chip

$0803 waveTableSynth Mac w/Apple Sound Chip

$0805 sampledSynth Mac w/Apple Sound Chip

$0806-$08FF reserved for Apple Mac w/Apple Sound Chip

$0900-$0999 free for Developers Mac w/Apple Sound Chip

$1001 noteSynth Mac Plus and SE

$1003 waveTableSynth Mac Plus and SE

$1005 sampledSynth Mac Plus and SE

$1006-$10FF reserved for Apple Mac Plus and SE

$1100-$1199 free for Developers Mac Plus and SE

You can specify which synthesizer to link to your channel by supplying one of the first three ID numbers ($0001 - $0005) as the second parameter to SndNewChannel. However, if the snd resource already contains a synthesizer ID (those created with MacRecorder do), you should pass zero (0) as the synth parameter. Only one synthesizer may be linked to a channel at a time, although multiple channels may be created and linked to the same synthesizer. This is because an active synthesizer “controls” the sound hardware until the sound channel is disposed. Two synthesizers vying for hardware control is sure to bring your Mac to its knees.

The Sound Manager will attempt to play your sound on the best equipment available. To do so, it determines which model of Macintosh the application is running on, and adds a constant to the requested synthesizer ID number. If the Macintosh is equipped with the Apple Sound Chip, then the constant $0800 is added. If not, then the constant $1000 is added. The Sound Manager will then try to use the ‘snth’ resource that corresponds to the new ID (original ID + constant). If the resource is not available, then the original resource ID is used. For example, if SndNewChannel is passed the sampled sound synthesizer ID ($0005) while the application is running on a Macintosh Plus, the Sound Manager will open the synth resource of ID $1005 since this is the sampled sound synthesizer for the Macintosh Plus. When run on a Macintosh II, the Sound Manager will open the synth resource of ID $0805, which is the sampled sound synthesizer for a Macintosh equipped with the Apple Sound Chip.

The ‘snth’ resources mapped to the Apple Sound Chip ($0801 - $0805) are written to take advantage of this added hardware. The Apple Sound Chip generates an audio/stereo signal, which is then filtered and buffered by two Sony sound chips. The Apple Sound Chip also contains a 1024 byte FIFO buffer to accept sound values. This permits the machine to frequently operate asynchronously of sound generation and to provide stereo capabilities. This chip is present on the Macintosh II series and following models.

If you did not create the snd yourself (with MacRecorder, for instance), you may not know what format it is or if a synthesizer has already been defined. In this case, use ResEdit to open the resource in hexadecimal form. The first word of the resource contains the format type (0001=Format 1, 0002=Format 2). If the snd is Format 1, you should then check the third word to determine if a synthesizer has already been chosen. If this word is anything other that 0000, pass zero as your synth ID when calling SndNewChannel. If no synthesizer is defined for this resource (third word = 0000), you should pass one of the three ID numbers specified for a general Macintosh (see chart above). If the snd is Format 2, you should pass zero as the synth parameter (snd’s of this format always use the sampled sound synthesizer, therefore the third word is not used to indicate a synth ID). Figure 2 shows an example of both Format 1 and Format 2 snd’s in hex form.

So, which synthesizer is the best suited for your snd resource? Glad you asked....

Figure 2.

snd Advice

As I mentioned earlier, snd’s come in two formats, format 1 and format 2. Format 1 is the more versatile of the two. It might only contain a sequence of sound commands describing a note to be played, or it may contain sampled sound or wave table data. Format 2 resources are used by the sampled sound synthesizer, and must contain a sampled sound. When SndPlay is called with a format 2 ‘snd ‘, it automatically opens a channel to the sampled sound synthesizer.

In either case, MacRecorder will make the proper synthesizer decision for you. When using snd’s created by MacRecorder, you need not be concerned with the synthesizer parameter in a call to SndNewChannel. Simply pass zero (0), and have the Sound Manager interrogate your resource for the needed information. In the event that you do need to pass a synthesizer to SndNewChannel, try not to lose sleep deciding which is the right one. Since every synthesizer understands the same basic set of sound commands, you can have the sound channel linked to any synthesizer you wish. If a synthesizer receives a command it does not understand, it is simply ignored. If you have no idea what sound data is contained in the resource (wave table, sampled sound, etc.), use the sampled sound synthesizer to process the commands. There are coding techniques you can use to deal with snd resources you did not create yourself, or dissect with ResEdit. This article will not attempt to show you these techniques. If you need this information, get a copy of SoundApp (application code from Jim Reeks described earlier).

Back in the Channel Again

The third SndNewChannel parameter is a long integer. This parameter indicates an INIT option (different than a startup document!) to be sent to the synthesizer when the sound channel is created. I pass zero (0) for this parameter, since any INIT procedures used in my program will come from the snd resource.

The forth and final parameter of SndNewChannel is a ProcPtr to a “userRoutine”. A userRoutine is a procedure or function that you write which the Sound Manager will execute when instructed to do so. For my userRoutine, I pass a procedure pointer to a callBack routine (refer to my LoadMusic procedure):

{4}

error := SndNewChannel(MySoundChannel, 0, 0, @myCallBack);

I want my userRoutine (the procedure named “myCallBack”) to be executed after the last sound command has been processed through the sound channel. In order for myCallBack to be executed, I must instruct the Sound Manager to do so by way of a sound command.

Take a look at my PlayMusic procedure. Here I construct the sound command used to tell the Sound Manager that myCallBack procedure should be executed. A sound command in THINK pascal is a record comprised of three fields. The first field (cmd) specifies the sound command number, the following two fields (param1 and param2) are the parameters of that sound command. This record corresponds to the 8-byte sound command format described earlier.

Of the sound commands, callBackCmd tells the Sound Manager to execute the userRoutine specified in SndNewChannel (in this case the procedure named “myCallBack”). Notice that param1 is zero (0), but that param2 is used to store my application’s A5 globals. This is straight from the Sound Manager documentation, folks:

“User Routines will be called at interrupt time and therefore must not attempt to allocate, move or dispose of memory, de-reference an unlocked handle, or call other routines that do so...If these routines are to use an application’s global data storage, it must first reset A5 to the applications A5 and then restore it upon exit. Refer to Macintosh Technical Note #208 regarding setting up A5.”

This means that the userRoutine (myCallBack) must set register A5 appropriately if it intends to use any globals. Since a CallBack procedure is passed both the sound channel it is linked to, as well as the sound command that triggered its execution, we can use the second parameter (param2) to store the application’s A5 information. For a detailed explanation, see both the Sound Manager documentation and the Technical Note mentioned above.

Play that Funky Music

After creating the sound command record, I make a call to SndPlay (refer to the PlayMusic procedure). I want asynchronous sound, so I pass the newly created sound channel (mySoundChannel) and TRUE as the asynch parameter. Remember that the Sound Manager will now take the sound commands from the snd resource, and queue them up in our channel. I want myCallBack to be executed after the last snd sound command has been processed, so I call the SndDoCommand function (as opposed to SndDoImmediate which would bypass the sound channel queue, sending the sound command directly to the synthesizer):

{5}

Function SndDoCommand(chan: SndChannelPtr; cmd: SndCommand; noWait: Boolean): 
OSErr;

I pass False as the noWait boolean parameter. If the parameter noWait is set to False and the sound channnel queue is full, the Sound Manager will wait until there is space to add the command. If noWait is True and the sound channel is full, an error message of “queueFull” is returned and the command is never sent.

Once the callback sound command is processed, myCallBack is executed. Here I set a flag (mySoundDone) to indicate that the last command has been processed and the sound has finished playing. Once my “flash menubar loop” receives this flag, it terminates and the next statement is executed (DisposeMusic). Be careful to dispose of your channel once the sound has finished playing. If you do not disposed of the channel properly, be prepared for a system crash. Remember that only one synthesizer may be active at a time, no exceptions. If you forget to clean up after your sound, another routine (such as SysBeep) may try to activate another synthesizer.

Gotcha

Before experimenting with the code, you should be aware of the possible “Gotchas” you may encounter. A Gotcha is a special situation (call it a crash, if you must) brought on by not reading the documentation thoroughly. A Gotcha has such a simple solution that it may take days before you find it. Using the Sound Manager, I ran into quite a few Gotchas. The special situations (ok, the crashes) were usually so severe that only the programmers switch was left in working order, which I used often. Here are a few of the Gotcha’s you may run into while working with sound (some annoying, some fatal):

The Sysbeep Blues: A SysBeep occurs before you have disposed of your sound channel (perhaps by user interaction with a Dialog).

Wave Table Shuffle: A Macintosh Plus or SE was instructed to use the Wave Table Synthesizer. Currently, this synthesizer does not function on those Macs.

Debugging Debauchery: Remember that the Debugging option in THINK Pascal adds about an additional 30% overhead to your application. When memory gets tight (as it will with large snd’s), things get ugly.

Incognito Sound Commands: THINK Pascal v3.0 provides the Sound.p unit needed to run my code. All sound command numbers (the ‘cmd’ field of the SndCommand data record) listed in the Sound Manager documentation are defined in this unit except one: callBackCmd. I had to add this constant myself, which was simple (callBackCmd = 13;).

MIDI Madness: Sound Manager documentation tells us not to bother using this synthesizer (whose ID was not even listed in the synthesizer table) with your own keyboard. Believe it.

program AsynchSoundDemo;
{This program was written to demonstrate}
{asnchronous sound generation on the Macintosh}
{using the Sound Manager.  Written in THINK}
{Pascal v3.0 by Aaron E. Walsh, expressly for}
{publication by MacTutor magazine.   6/1/90}
 uses
 Sound;

 var
 mySoundDone: boolean;
 mySoundHandle: handle;
 SndResource: integer;
 mySoundChannel: SndChannelPtr;
 error: OSerr;
 mySoundCommand: Sndcommand;
{=========================}
 procedure DisposeMusic;
 var
 quietnow: boolean;
 begin
 quietnow := false;
 hpurge(mySoundHandle);
 error := SndDisposeChannel(mySoundChannel, quietnow);

 if error <> NoErr then
 FlashMenuBar(0);

 if gethandlesize(mySoundHandle) > 0 then
 ReleaseResource(mySoundHandle);
 end;
{=========================}
 procedure myCallBack (chan: SndChannelPtr;
 cmd: SndCommand);
{userRoutine to be called when the last sound}
{command has been processed. A5 code used    }
{to access globalsfrom S.M. documentation.   }
 var
 theA5: Longint;
 begin
 theA5 := SetA5(cmd.param2);
{Get/Set A5 so globals are available}

 mySoundDone := true;
 theA5 := SetA5(theA5);
{Set A5, as in S.M. documentation}
 end; {DisposeMusic}
{=========================}
 function LoadMusic: boolean;
 begin
 SndResource := 15944;
{Resource ID of the ‘snd ‘ resource to play}

 mySoundHandle := GetResource(‘snd ‘, SndResource);
{we need a handle to the resource}

 movehhi(mySoundHandle);
{move into high memory}

 hlock(mySoundHandle);
{lock it down, call me paranoid}

 hnopurge(mySoundHandle);
{make it unpurgeable, call me untrusting}

 mySoundChannel := nil;

 error := SndNewChannel(mySoundChannel, 0, 0, @myCallBack);
{create our own sound channel for asnch. ability}

 if error <> NoErr then
 LoadMusic := False
 else
 LoadMusic := True;
 end;
{=========================}
 procedure PlayMusic;
 var
 noWait: boolean;

 begin
 with mySoundCommand do
 begin
 cmd := callBackCmd;
 param1 := 0;
 param2 := SetCurrentA5;
{use param2 to stash A5.  We will use need}
{globals in the callback routine}
 end;

 noWait := False;

 if error = NoErr then
 error := SndPlay(mySoundChannel, mySoundHandle, TRUE);
{begin asynchronous sound play}

 if error = NoErr then
 error := SndDoCommand(mySoundChannel, mySoundCommand, noWait);
{add the callBack command to the sound channel queue}
 end; {PlayMusic}
{=========================}
begin  {main}
 mySoundDone := false;
 if LoadMusic then
 PlayMusic;
 repeat
 flashmenubar(0);
{flash menubar to demonstrate asyncronous sound generation}
 until button or mySoundDone;
 DisposeMusic; {clean up, or crash}
end.

 
AAPL
$117.60
Apple Inc.
-1.03
MSFT
$47.47
Microsoft Corpora
-0.12
GOOG
$541.08
Google Inc.
+1.81

MacTech Search:
Community Search:

Software Updates via MacUpdate

MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more
Carbon Copy Cloner 4.0.3 - Easy-to-use b...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
ForeverSave 2.1.3 - Universal auto-save...
ForeverSave auto-saves all documents you're working on while simultaneously doing backup versioning in the background. Lost data can be quickly restored at any time. Losing data, caused by... Read more
Voila 3.8.1 - Capture, annotate, organiz...
Voila is a screen-capture, recording, and annotation tool that is a full-featured replacement for Mac's screen-capture and screen-recording capabilities. It has a large and robust set of editing,... Read more
SyncTwoFolders 2.0.6 - Syncs two user-sp...
SyncTwoFolders simply synchronizes two folders. It supports synchronization across mounted network drives and it is a possibility to run a simulation showing in a log what will be done. Please visit... Read more
Duplicate Annihilator 5.1.1 - Find and d...
Duplicate Annihilator takes on the time-consuming task of comparing the images in your iPhoto library using effective algorithms to make sure that no duplicate escapes. Duplicate Annihilator detects... Read more
HandBrake 0.10.0 - Versatile video encod...
HandBrake is a tool for converting video from nearly any format to a selection of modern, widely supported codecs. Supported Sources: VIDEO_TS folder, DVD image or real DVD (unencrypted -- CSS is... Read more

Latest Forum Discussions

See All

Tilt to Live Bundle Set to Arrive This T...
Tilt to Live Bundle Set to Arrive This Thanksgiving Posted by Ellis Spice on November 25th, 2014 [ permalink ] One Man Left has unveiled an upcoming Tilt to Live bundle, allowing players to get the series for a di | Read more »
BattleLore: Command (Entertainment)
BattleLore: Command 1.0 Device: iOS Universal Category: Entertainment Price: $9.99, Version: 1.0 (iTunes) Description: ***NOTE: Compatible with iPad 2/iPad mini, iPod touch 5 and up and iPhone 4S and up – WILL NOT RUN ON EARLIER... | Read more »
Weather Or Not Review
Weather Or Not Review By Jennifer Allen on November 25th, 2014 Our Rating: :: STYLISH WEATHER REPORTINGiPhone App - Designed for the iPhone, compatible with the iPad Check the weather quickly and conveniently with Weather or Not... | Read more »
The All-New Football Manager Handheld 20...
The All-New Football Manager Handheld 2015 is Available Now Posted by Jessica Fisher on November 25th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Six iOS Games to Get You Ready for Thank...
Image Source: Friends Wiki At this point in the month, you or at least a few people you know are probably getting ready to scramble around (or are already scrambling around) for Thanksgiving Dinner. It’s a hectic day of precise oven utilization, but... | Read more »
Call of Duty: Heroes: Tips, Tricks, and...
Hello Heroes: What’d we think of Call of Duty‘s take on Clash of Clans? Check out our Call of Duty: Heroes review to find out! Just downloaded Call of Duty: Heroes and need some handy tips and tricks on how to get ahead of the rest? As we often do,... | Read more »
Call of Duty: Heroes Review
Call of Duty: Heroes Review By Jennifer Allen on November 25th, 2014 Our Rating: :: CLASH OF FRANCHISESUniversal App - Designed for iPhone and iPad Mix Clash of Clans with Call of Duty, and this is what you get.   | Read more »
Slider Review
Slider Review By Jordan Minor on November 25th, 2014 Our Rating: :: SLIDE TO PLAYUniversal App - Designed for iPhone and iPad Slider has all the excitement of unlocking your phone screen.   | Read more »
oh my giraffe (Games)
oh my giraffe 1.0.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0.0 (iTunes) Description: Eat fruits while being chased by lions. Cut the vines to send fruit plummeting onto the lions. Don't worry, your flexible... | Read more »
One of 2000’s Most Loves Adventure Games...
One of 2000’s Most Loves Adventure Games, The Longest Journey, has Come to iOS Posted by Jessica Fisher on November 25th, 2014 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Early Black Friday MacBook Pro sale: 15-inch...
 Best Buy has posted early Black Friday prices on 15″ Retina MacBook Pros, with models on sale for $300 off MSRP on their online store for a limited time. Choose free local store pickup (if available... Read more
A9 Chips Already?
It’s barely more than a couple of months since Apple got the first A8 systems-on-chip into consumer hands, but rumor and news focus is already turning to the next-generation A9 SoC. Apple Daily... Read more
NewerTech Announces NuGuard KXs Impact X-Orbi...
NewerTech has announced updates to its family of Impact X-Orbing Screen Armor bringing military grade, triple layer protection to Apple’s new iPhone 6 and 6 Plus. Like all models in the NuGuard KXs... Read more
13-inch 1.4GHz MacBook Air on sale for $889,...
 B&H Photo has the 13″ 1.4GHz/128GB MacBook Air on sale for $889 including free shipping plus NY tax only. Their price is $110 off MSRP. B&H will also include free copies of Parallels Desktop... Read more
Save up to $300 on Macs and iPads with your A...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Apple refurbished Mac Pros available for up t...
The Apple Store is offering Apple Certified Refurbished Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more
Jumptuit Launches One-Tap Windows 8.1 iTunes...
Jumptuit has launched Windows 8.1 support for One-Tap iTunes Sync. with which Windows 8.1 users can now easily sync their iTunes libraries with Microsoft OneDrive. Jumptuit provides easy access from... Read more
Apple restocks refurbished 13-inch 2014 Retin...
The Apple Store has restocked Apple Certified Refurbished 2014 13″ 2.6GHz Retina MacBook Pros for up to $230 off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
CEA Study Finds More People Recycling Electro...
A new study by the Consumer Electronics Association (CEA) finds that electronics recycling receives the continued and growing support of consumers. According to the CEA,s Recycling and Reuse Study,... Read more
15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale today for $1749. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of Parallels Desktop... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.