A COM-based Automation Wave File Editor

  WaveEditAuto.gif (7152 bytes)

Background/Overview

This article takes the original programming idea from the Wave File Editor Control and extends the application's functionality into a client/server application set.
The WaveEdit app can now be used as a stand-alone program or as a server, controlled by client applications written in VC++ or VB.

Making the transition from stand-alone application to client/server has become easier due to MFC's built-in automation support (faster/easier development at the expense of increasingly bloated code).
If you look at the original Wave Editor Control code, the functionality for graphing is encapsulated within a CWnd derived object - all very nice and modular and easy to move around, but within the context of MFC automation, maybe too unnecessarily complicated.
So to simplify, I took the functionality out of the WaveEditCtrl class and put it in the server's OnPaint handler.

IDispatch, Type Libraries and Stuff

To enable communication between applications (Automation), COM provides the IDispatch interface. IDispatch permits COM objects to expose functions, data and events to the outside world, allowing other applications to control these programmable objects. Although the IDispatch interface can be queried at runtime so that a client can know which data and functions are supported by the object, this requires creation of an instance of the object and may not be what we want in terms of flexibility. This is where the Type Library comes in and acts as a sort of #import library for COM objects.
Using type libraries within our automated applications provides us with information about the interfaces supported and the methods that each interface supports - regardless of whether our COM object has been created or not.

Basic Recipe

I found it easiest to create the code by following a cookbook recipe, starting from scratch - two individual AppWizard generated SDI applications with automation support added. With initial automation support you get an automation skeleton consisting of initialization code for the application's InitInstance() function, a dispatch map within the document class and a type library. Adapting the WaveEditCtrl code into the server proved not too difficult - basically, moving the initial caret positioning into the view's OnInitialUpdate().

Programming Flow

                               WaveEditAuto2.gif (4296 bytes)

Initialization - The server application exposes its functionality to the outside world through its COM enabled IWaveEdit interface in the form of various methods that are called from the client application.
When the client launches, it creates an object of the IWaveEdit interface, looks for it's CLSID in the registry and creates the IDispatch object. This gives the client access to the server's methods providing the ability to launch the server with the client.
Because the default nature of an automation server is to be invisible - we need to call three methods when launching the client, ShowApp(), ShowWindow() and SetCursor(). These methods allow the server to launch in an identical manner to it's stand-alone counterpart.
These three methods respectively allow the server's main window and view to become visible as well as placing the blinking cursor in it's initial position within the client area.

Interaction - When the client Play button is clicked, it's timer starts the stopwatch in the client's StatusBar and calls the server method - SetPlay() which in turn starts it's own timer and sends the cursor on it's merry way.
Similar server methods are called for the client's Pause and Stop buttons.

So when does the client's stopwatch know when the server has finished playing it's wave file?
The IsWaveEnd() method of course! - The client continually calls this method when it's timer is running to check the status.If the caret reaches the full width of the server's client area it sets the IWaveEdit boolean property - result. Once result returns true, the client timer simply kills itself.


void CWaveEditClientView::OnTimer(UINT nIDEvent) 

{
	...
	m_waveEditObject.IsWaveEnd();
	if (m_waveEditObject.result){
	KillTimer(1);

	m_bPlaying = FALSE;

	}
	...
}

Definitly not the most complex COM-based app around, but should be of interest if you wish to automate some of your own code ideas.
BTW, sorry about the On/Off buttons - they might indicate to you that a COM object is being created through a class factory, or an IUnknown interface pointer is being released - I assure you that they simply show and hide the server application!
The screen redraw of the server app is annoying when clicking the client play button. But remember, in this simplified code we just draw random lines - in an audio application you would reload the same samples from the same wave file.

Download demo project - 124 KB



Comments

  • Audio Signals

    Posted by Legacy on 07/10/2002 12:00am

    Originally posted by: Jankiraman.E

    How to get the waveform of an audio signal(external Device)

    Reply
  • How about dual interface for access from VBA?

    Posted by Legacy on 03/27/2002 12:00am

    Originally posted by: Michael Carr

    I'm looking for an example similar to this one except where a dual interface is implemented. That way I can access it from VBScript codes, etc... Could you implement a dual interface in this example? I like your example because it is simpler than the ones that ship with Visual Studio...

    Reply
  • Why You not support Events for automation.

    Posted by Legacy on 01/11/2001 12:00am

    Originally posted by: Nenad

    AUTHOR: " So when does the client's stopwatch know when the server has finished playing it's wave file?

    The IsWaveEnd() method of course! - The client continually calls this method when it's timer is running to check the status.If the caret reaches the full width of the server's client area it sets the IWaveEdit boolean property - result. Once result returns true, the client timer simply kills itself. "


    I think better way to do that is whit Events .

    Nenad.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds