|By Berndt Hamboeck||
|August 1, 2004 12:00 AM EDT||
Last year at this time we were building an MP3 player using PowerBuilder. This year I'd like to go one step further and use the latest available technologies and versions of the tools provided by Sybase to build an MP3 jukebox.
I have to say that this was not my idea. This idea was born at a Christmas party where some computer freaks were sitting in a corner (yes, we were drinking some beer) and talking about our new little helpers, the Pocket PCs. We agreed that these toys were very cool. They're also very handy in the car when they act as mobile GPS systems and provide directions. (If you're married you may already be in the situation where the human GPS system sitting next to you tells you: left, left, now left....why are you moving left, I meant this left [pointing to the right].) But one thing is missing: we wanted to play MP3 files in the living room and be able to choose the music from our mobile toy: the Pocket PC. This was the moment in which the jukebox idea was born and the results are presented to you here.
What Do We Need?
Everything we need comes from Sybase, except the MP3 files you want to play. Once you have the music files on your hard disk (either by downloading free MP3 files or by ripping them on your own), install Sybase EAServer 5.0 - which will act as the "jukebox" - and PowerBuilder 9 or 10. PowerBuilder 10 makes it easier to publish NVOs as Web services by performing all the necessary steps (like registering the Web service and generating the WSDL file on the server) on its own. A great feature, but if you still go with PowerBuilder 9 check out the Web service plug-in for Eclipse, the open and free Java IDE, that's included with your EAServer installation disk. The last and final product we need is PocketBuilder, which will send a request to our jukebox for a particular MP3 file. You can see the complete setup in Figure 1.
The MP3 File Format
MP3 music files are CD-quality compressed recordings that occupy approximately one tenth to one twelfth less file space than the equivalent CD format WAV file; this is achieved by filtering out all noise that is not detectable to the human ear. MP3 compression is based on a psycho-acoustic model that recognizes that the human ear cannot hear all the audio frequencies of a recording. The human hearing range is between 20Hz to 20Khz and is most sensitive between 2-4 KHz. When sound is compressed into an MP3 file, an attempt is made to get rid of the frequencies that cannot be heard. This is known as "destructive" compression. After a file is compressed, the data that is eliminated in the creation of the MP3 cannot be replaced. Another thing that MP3 does is eliminate parts of the audio that we cannot hear. Our ears are quite limited - after hearing something loud, we cannot hear quiet sounds for a short period of time. The MP3 codec calculates and deletes that part. This is how MP3 achieves its great compression ratio without the apparent loss of quality. When encoding a file into the MP3 format, a variety of compression levels can be set. For instance, an MP3 created with 128Kbit compression will be a better quality and larger file size than that of a 56Kbit compression; thus, the more the compression level decreases, the poorer the sound quality is.
EAServer, PowerBuilder, PocketBuilder, and Web Services
We want to provide a list of MP3 files to our users. The user should then be able to pick a title and the server will start playing it. The list of available music files will be sent upon request to a client. The client will send the request via a Web service (for the song list or the song to play) and EAServer will answer it by acting on the request (by sending the MP3 list or by playing the file locally). Previous articles in PBDJ covered some of the fundamentals of Web services in EAServer and PocketSoap, which we'll use for our PocketBuilder client to send the request (see Recommended Reading section).
We'll start with the server component written in PowerBuilder, which will be exposed as a Web service within EAServer. The component offers the following functions:
- A list of MP3 files to the client (in my simple example it will read all files from a directory on the server and send this list to the client).
- Plays and stops a particular MP3 file, which the client has chosen from a list sent earlier. The server component looks for the file in its directory and starts playing the file locally. If the client requests to stop the file, the music should stop.
ls_ret = Space(200)
ll_len = Len(ls_ret)
ls_cmdToDo = "open " + as_title + " type MPEGVideo Alias MP3Play"
ll_return = mciSendString(ls_cmdToDo, ls_ret, ll_len, 0)
To get the filelist I used more WinAPI calls. If you're interested in the full source code I have posted it on CodeXchange (the package includes the server-side component and also a PowerBuilder and PocketBuilder client as described here).
A nice new feature in PowerBuilder 10 is that we can expose a component directly as a Web service from within PowerBuilder. Just look at the component's properties in the project painter (see Figure 2). You no longer need to use the Eclipse plugin for EAServer to make a component available as a Web service during deployment of the component. You also don't need to use the EAServer manager to create and compile stubs and skeletons for the component.
We want to implement two clients, one written in PowerBuilder and the other in PocketBuilder. It's possible to use just one code basis for both versions; however, I wanted to use the new Web service client enhancements in PowerBuilder 10 that are not available in PocketBuilder. Therefore we'll have to use PocketSOAP to communicate with EAServer from PocketBuilder. We'll build the client, from which we'll be able to fire an MP3 media file on the server (see Figure 3). In order for a client to call our Web service, we need to provide a WSDL file that defines the interface to a Web service. When we publish our component the WSDL file is created for us within EAServer. To access the WSDL file through our PowerBuilder client in order to create a proxy, we use the new Web service Proxy Wizard (see Listing 2). We just enter the URL to the WSDL file and the project will create a proxy object into our client library. To use the proxy object don't forget to add the needed SOAP objects to the Library Search Path (simply add %Sybase%SharedPowerBuilder pbsoapclient100.pbd) and don't forget to distribute that PBD with your application. The next step is to code the call of the Web service to get the file list (which you can see in Figure 3) and to start and stop the MP3 file on the server.
To implement the mobile client using PocketBuilder, we have to implement some things differently. At the moment PocketBuilder has no direct EAserver support or Web services support. To overcome this we'll use PocketSOAP, an open source SOAP client COM component for the Windows family, originally targeted at the Pocket PC (therefore the name PocketSOAP). However, there is also a free Win32 version that works on Windows 95/98/Me/NT4/2000/XP. Download PocketSOAP for free at www.pocketsoap.com. You'll find an interface for PocketBuilder on CodeXchange; it's an external DLL that provides simple access to the PocketSOAP package (don't forget to deploy the dll to the Windows directory on your Pocket PC). You see the actual implementation for PocketBuilder in Listing 3.
- An MP3 file should be played locally. However, the problem is that Web services are not very good for transmitting binary data. One solution would be to send a URL to the client from where the file could be downloaded to the Pocket PC. (Remember that the INET object is not supported in PocketBuilder in its most current version [1.5.2] when this article was written.) To play the file on your handheld you could launch the MediaPlayer with the CreateProcess API (which is already declared in the downloadable application) with the media file as one of the command-line parameters:
CreateProcessW("Program FilesWindows Media Player
8player.exe",ls_mp3File, 0, 0, 0, 0, 0, 0, 0, 0)
- It would be very cool to let the user generate individual playlists and choose songs from different records from different interpreters.
- WAV files can be played by using the MCI functions so it's easy to enhance the jukebox to play, for example, a complete or part of a CD that's in the CD/DVD drive of your server machine.
- AVI files can be played by using the MCI functions, so it would be cool to show the video clip instead of MP3 files.
Sybase is doing a good job of providing developers with all the tools needed to not only build enterprise applications, but also applications that entertain people. Such applications can easily be written with these tools, such as a wide variety of games or the jukebox we have written today.
As you've seen, it's very straightforward to create both a standard and a mobile client. This particular project is still in the early stages (though it already works and does a good job) but it can easily be enhanced. For example, the application could be extended to support some sort of video station (maybe to display music videos instead or in addition to sound files). The full project is available on CodeXchange (http://codexchange.sybase.com) or on Pocket PC.com (www.pocketpc.com). Feel free to enhance it and if you have any questions please don't hesitate to contact me; I'm always glad to be of any help. The tools needed are EAServer, PowerBuilder 9 or 10 for the standard client, and PocketBuilder to build the mobile client. You'll also need PocketSOAP for the mobile client, which is also a free download. I wish you happy coding and have fun at your sessions at TechWave 2004!
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- Creation and Consumption of Web Services with PowerBuilder
- Cloud People: A Who's Who of Cloud Computing
- DDDW Tips and Tricks
- Cloud Expo 2011 East To Attract 10,000 Delegates and 200 Exhibitors
- Working with SOA & Web Services in PowerBuilder
- Dynamically Creating DataWindow Objects
- OLE - Extending the Capabilities of PowerBuilder
- DataWindow.NET How To: Data Entry Form