" Monopoly ? No, we just don't want any competion "

Just when you think you've got the computer industry sorted out, along comes a piece of news that junks all your old assumptions. All this time we thought of SONY as a company that makes Televisions, Walkmans, Decks and other home appliances. Suddenly, it shocks us all by coming out with the worlds first VRML 2.0 browser, CyberPassage. Just as we were recovering from the effects of these tidings, along came another shocker, Intel, the worlds largest manufacturer of computer chips, is coming out with some new software !! I mean, now I wouldn't be too surprised to discover that Microsoft plans to produce the next generation of Pentiums chips !!
When the guys from Silicon Valley said "Intel Inside", they really meant it !! Intel already makes a large percentage of the computer components floating around in the market and some speculate that it might take on the giants by producing its own Operating System !! Having an intimate knowledge of its own processors, Intel can now produce some top class applications which utilize the complete power of their processors.

Look out Microsoft !!, here comes some real competition !!

The product that's causing all the commotion is RSX or Realistic Sound eXperience It's an OCX that can produce realistic 3D sound and because it uses OLE technology, it can be ported into most existing applications, like Power Builder or Visual Basic. This means that we can now have realistic sound in our VRML worlds, as well as in any application under Windows 95.

Did I mention realistic sound ? ....

Imagine creating a VRML model of a solar system, suspended in the cold, dark and silent depths of space. Now imagine having multi-hued planets whizzing about around a central star, going about their business as planets do. As you approach a planet, the volume of it's sound increases, until it screams past you, gradually letting silence take over again. As you slowly float over to the star, the volume of the combined 'music of the spheres' increases until they all spin about you, their whispering song a collective, melodious symphony......

Imagine being able to create the model of a virtual Opera House, with a show in full swing. The wooden stage ablaze with the reflected light of a thousand bulbs. The singers, in full regalia, stride about the boards as they sing out their story. Imagine being able to glide silently over to the stage, the music growing with every step, until atlast, it rises to an unbearable crescendo and then slowly dies away, alive no more....

Imagine creating a extraordinarily realistic game, in which the participant is totally immersed in a virtual and very hostile environment. As he stalks through the enemy fortress, he suddenly hears the sound of guards approaching from the rear. Hurriedly he ducks into a dark niche in the stone wall, his weapon in his hand. Safety off, he awaits his pursuers as their footsteps draw closer and closer.....

Or how about doing something a little more prosaic, like creating a business program that talks back to you !! If you make an error, it'll immediately ask you to rectify it and if you let it, it'll keep bombarding you with tips and tricks until your deaf !! Not only that, at a business meeting, it'll entertain your audience by keeping up a running commentary on all the graphs you've created, quoting stock prices and profits as the figures march across the screen .....

Well, you get the picture.

The ingredients.....

The minimum hardware requirements to use RSX aren't very steep. We worked on a Pentium 66, with 16 MB RAM, a large hard disk and a display adapter set to 256 colors. We also had a sound card ( Creative SB16 ) installed. Even though we haven't tried it on anything slower, we're quite certain that it will work adequately on a 486 DX.

The software can be downloaded from Intel's site on the Web. Simply follow the instructions on their page, you just can't go wrong. The software will automatically install itself onto your machine.

Once you've installed the software, copy the file aaudio.h into the new directory, or set the include to cover the directory the file is present in. When you try Intel's samples, make sure you do the same thing there.

Find out what you don't do well and then DON'T DO IT !!!!

Since we'll be discussing an OCX here, it is quite necessary for you to be fluent in OLE 2.0. If you don't know OLE 2.0, then all of this is going to bounce right of your head. Another thing, this code has been written using the Microsoft Foundation Classes ( MFC ). It is possible to use C, but we don't recommend it. Infact, we down right discourage you from trying to write it in C, C++ is the way to go.

Enough chit chat, it time to hit the books, lets try out the first example.

The Beginning ....


#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE;

class yyy : public CFrameWnd
{
public:
void bb()
{	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
	IID_IAAudio,(void ** ) & m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()

class zzz : public CWinApp
{
public:
	int InitInstance()
	{
		yyy *b = new yyy;
		b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
		b->ShowWindow(3);
		CoInitialize(NULL);
		m_pMainWnd=b;
		return 1;
	}
};
zzz a;

The first thing we'll look at is InitInstance, which says CoInitialize . This function is needed to set up Ole 2.0 for your program. You don't need to know any more about it , just that if it wasn't there OLE 2.0 wouldn't work

Now lets take a closer look at the function bb. Since we've assumed you know MFC programming, you'll be aware of the fact that the function bb will be called every time you click on the menu option. In bb we have CoCreateInstance, which is the first function normally used with OLE 2.0, because this function will load an OLE server into memory. Now the question is, which server should be loaded ? The first parameter of the function CoCreateInstance is CLSID_AAudio, which is nothing but a structure defined in the header file, aaudio.h. Using CLSID_AAudio, CoCreateInstance will get the number that represents the OLE server. The Ole server comes along with the RSX software, so we don't have to worry about anything, because RSX registers this server at the time of its installation. The second parameter is a 0 and we need not worry about either. The third parameter, CLSCTX_INPROC_SERVER means that the server is going to be a .dll file and not a .exe file. We're also using IID_IAudio, which is nothing but a # define in the header file aaudio.h and which stands for yet another number. This number help you locate the IAudio interface.CoCreateInstance will, if successful, return a pointer to the IAudio interface which will be stored in m_lpAA . In short CoCreateInstance will load the server into the memory, and it will also return a pointer to an interface. Now, just for the ones who don't know OLE 2.0 , a pointer to an interface is the same as a pointer to a class. This interface (or class) has certain methods or certain functions. The code for these functions are present in the .dll. This .dll, or to be more specific, the function code, has been written by (who else ) Intel. Now once we have loaded our server into memory, we create what is known as an IAudioListener. We do this because the interface has two important functions, one of which is called CreateListener ( which quite obviously means create a listener for the sound ). Now the first parameter we supply to CreateListener is a structure that looks like AALISTENERDESC ( Complicated name no ?! ). a1Desc stands for this structure and contains just two members, one of which is named dwUser. This member (dwUser) of the structure makes it possible for you to have multiple users or listeners , each of whom must have an individual number. We chose 50 because the original program from Intel had set dwUser to 50. You however you can choose any number you want. This number is of importance only when you have more than one listener, which is not applicable in our case.

The listener is the one who will listen to the sound and he has to have an initial position in the window. To do this we initialize hMainWnd to AfxGetMainWnd()->GetSafeHWnd(). Now if you don't understand what AfxGetMainWnd()->GetSafeHWnd() means, don't fret over your ignorance, all you need to know that it returns a handle to the window. Instead of doing it in this way, you could initialize hMainWnd to m_hWnd, which is a member in CFrameWnd.

So CreateListener will return an address which points to an IAudioListener, stored in m_lpAL. In other words m_lpAL will now be your listener. But just having a listener is of no use, someone has to emit the sound. So you have to create another structure, one that looks like AAEMITTERDESC and whose members we have to initialize. One of the members is named dwUser, to which we give the same number that we gave to dwUser ( of AALISTENERDESC ). An emitter will obviously generate or emit some sound, which the listeners can hear. So the emitter must also have a number for its own reference. Since the job of the emitter is to emit a sound (usually from a .wav file ), we initialize the szFilename member of the structure to cppmin.wav (a sound file that comes along with the Intel Development System) . Now since lpAE stands for the emitter which is all set to perform the specified file, all we need to do now is play the file. So AA_PLAYLOOP, which is a #define in the header file, is given to ControlMedia ( a part of the emitter interface ), which plays the file continuously. You can control the behaviour of the .wav file by using ControlMedia. So now we have an attentive listener ( a rarity ) and an emitter that just doesn't stop blabbing ( you don't have to look hard to find one of those !! ).

Now you'll probably turn around and say, " So what's so ground breaking about this ? Even Microsoft has classes that play .wav files !". Our answer, " This is only The Beginning !! " .

Before we proceed any further, lets review what we've done so far.

We first loaded an OLE Server into memory and from there we called two functions, CreateEmitter and CreateListener. By doing this we created an emitter and an listener and so created sound. It's really that simple !!

In this next example the base logic is the same, we've just added a few basic visual effects so that you can grasp the concept better.

#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
VECTOR3D v3d;
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE;

class yyy : public CFrameWnd
{
public:
void bb()
{
	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
				IID_IAAudio,  (void ** ) &m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
}
void OnLButtonDown(UINT,CPoint e)
{
	CClientDC d(this);
	d.TextOut(e.x,e.y,"L");
	v3d.x = e.x/100;v3d.y = e.y/100;v3d.z = 0;
	m_lpAL->SetPosition(&v3d);
}
DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
ON_WM_LBUTTONDOWN()
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()

class zzz : public CWinApp
{
public:
	int InitInstance()
	{
		yyy *b = new yyy;
		b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
		b->ShowWindow(3);
		CoInitialize(NULL);
		m_pMainWnd=b;
		return 1;
	}
};

zzz a;

Now wherever you click on the window, you will see an L ( for Listener ). What we have done is called a function named SetPosition and we've passed to it a structure that looks like Vector3D. Vector3D has three fields, x,y,z. Now whenever you click the mouse in the window, the coordinates are relayed to the CPoint structure. We 're using e, a variable that looks like CPoint, to refer to the click coordinates (which we simply divide by 100 to stick to the proper scale ). These values are then given to Vector3D and the vector details are then transferred to SetPosition.

You'll soon realize that the closer you click to the emitter, at position 0,0,0 ( Upper left hand corner ), the louder the sound gets and the further away you click, the fainter the sound gets.

If you're getting lost in the maze of L's you've created, minimize and then maximize the window, or add an Invalidate option in the function . ( I said that the effects would be basic ! ).

Lets look at Program no. 3, another version of program no. 2.

#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
VECTOR3D v3d;
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE;

class yyy : public CFrameWnd
{
public:
void bb()
{
	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
				IID_IAAudio,(void ** ) &m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
}
void OnLButtonDown(UINT,CPoint e)
{
	CClientDC d(this);
	d.TextOut(e.x,e.y,"L");
	v3d.x = e.x/100;v3d.y = e.y/100;v3d.z = 0;
	m_lpAL->SetPosition(&v3d);
}
void OnRButtonDown(UINT,CPoint e)
{
	CClientDC d(this);
	d.TextOut(e.x,e.y,"E");
	v3d.x = e.x/100;v3d.y = e.y/100;v3d.z = 0;
	m_lpAE->SetPosition(&v3d);
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()

class zzz : public CWinApp
{
public:
	int InitInstance()
	{
		yyy *b = new yyy;
		b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
		b->ShowWindow(3);
		CoInitialize(NULL);
		m_pMainWnd=b;
		return 1;
	}
};
zzz a;

Program no. 3 is almost identical to the previous one, the only difference being that here we're trapping the right mouse click also. When we say RButtonDown all that we are doing is calling SetPosition again. This function is being called from m_plAE, which looks like the structure for the emitter. So if you right click in the window, you will see an E, for emitter. If you left click in the window, you will see an L, for listener. Depending on the distance between the emitter and the listener, the sound volume will change.

After you've spent some hours drooling over this example, head over to the next one.

On to Program no. 4

#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
VECTOR3D v3d;
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE,*m_lpAE1;
AAEMITTERMODEL aeModel;

class yyy : public CFrameWnd
{
public:
void bb()
{
	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
				IID_IAAudio, (void ** ) &m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
	strcpy(aeDesc.szFilename,"bird01.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE1, NULL);
	m_lpAE1->ControlMedia(AA_PLAYLOOP);
	v3d.x = 0;v3d.y = 0;v3d.z = 0;
	m_lpAE->SetPosition(&v3d);
	v3d.x = 5;v3d.y = 3;v3d.z = 0;
	m_lpAE1->SetPosition(&v3d);
}
void OnLButtonDown(UINT,CPoint e)
{
	CClientDC d(this);
	d.TextOut(e.x,e.y,"L");
	v3d.x = e.x/100;v3d.y = e.y/100;v3d.z = 0;
	m_lpAL->SetPosition(&v3d);
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()

class zzz : public CWinApp
{
public:
	int InitInstance()
	{
		yyy *b = new yyy;
		b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
		b->ShowWindow(3);
		CoInitialize(NULL);
		m_pMainWnd=b;
		return 1;
	}
};
zzz a;

What we have done in Program no. 4, is go a step further and introduce a second sound source in the window, at the bottom right hand corner. We now have two emitters, m_1pAE and m_1pAE1. The former is the original sound and the latter can be any .wav file of your choice. We used the bird01.wav file that came with the SONY VRML samples. Now, depending on where you click, you will hear either a combination of the two sounds or if you click near the any of the two sound emitting corners, one clear .wav file. With two emitters and one listener, depending on where you are, you will hear a different proportion of either sound.

In this next program we utilize mouseMove for a smoother aural effect.

#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
VECTOR3D v3d;
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE,*m_lpAE1;
AAEMITTERMODEL aeModel;

class yyy : public CFrameWnd
{
public:
void bb()
{
	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
				IID_IAAudio,(void ** ) &m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
	strcpy(aeDesc.szFilename,"bird01.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE1, NULL);
	m_lpAE1->ControlMedia(AA_PLAYLOOP);
	v3d.x = 0;v3d.y = 0;v3d.z = 0;
	m_lpAE->SetPosition(&v3d);
	v3d.x = 5;v3d.y = 3;v3d.z = 0;
	m_lpAE1->SetPosition(&v3d);
}
void OnMouseMove(UINT,CPoint e)
{
	v3d.x = e.x/100;
	v3d.y = e.y/100;
	v3d.z = 0;
	if (m_lpAL) 
		m_lpAL->SetPosition(&v3d);
}
DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
	ON_WM_MOUSEMOVE()
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()

class zzz : public CWinApp
{
public:
int InitInstance()
{
	yyy *b = new yyy;
	b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
	b->ShowWindow(3);
	CoInitialize(NULL);
	m_pMainWnd=b;
	return 1;
}
};
zzz a;
Now you no longer need to click in the window to hear sound, just move the mouse pointer around. Remember that since mouseMove gets called at the start, you will have to make sure that the listener pointer has a initial value, otherwise a General Protection Error will occur.

The last program changes the intensity of the sound that you hear.

#include <afxwin.h>
#include <afxext.h>
#define INITGUID	
#include "aaudio.h"
HRESULT h;
IAAudio* m_lpAA;
IAAudioListener* m_lpAL;
AALISTENERDESC alDesc;        
VECTOR3D v3d;
AAEMITTERDESC aeDesc;
IAAudioEmitter* m_lpAE,*m_lpAE1;
AAEMITTERMODEL aeModel;
float z = 1,z1=7;

class yyy : public CFrameWnd
{
public:
void bb()
{
	h=CoCreateInstance(CLSID_AAudio,0,CLSCTX_INPROC_SERVER,
				IID_IAAudio, (void ** ) &m_lpAA);
	alDesc.hMainWnd = AfxGetMainWnd()->GetSafeHwnd();
	alDesc.dwUser = 50;
	m_lpAA->CreateListener(&alDesc, &m_lpAL, NULL);
	strcpy(aeDesc.szFilename,"cppmin.wav");
	aeDesc.dwUser = 50;
	m_lpAA->CreateEmitter(&aeDesc, &m_lpAE, NULL);
	m_lpAE->ControlMedia(AA_PLAYLOOP);
}
void OnLButtonDown(UINT,CPoint e)
{
	z++;
	aeModel.minFront = 5.0f;
	aeModel.maxFront = 200.0f;
	aeModel.minBack = 5.0f;
	aeModel.maxBack = 200.0f;
	aeModel.intensity = z;		
	m_lpAE->SetModel(&aeModel);
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(yyy,CFrameWnd)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(100,bb)
END_MESSAGE_MAP()
class zzz : public CWinApp
{
public:
	int InitInstance()
	{
		yyy *b = new yyy;
		b->Create(0,"hi",WS_OVERLAPPEDWINDOW,(CRect)0,0,"aaa");
		b->ShowWindow(3);
		CoInitialize(NULL);
		m_pMainWnd=b;
		return 1;
	}
};
zzz a;

To change the strength of the signal, create a structure that look like AAEMITTERMODEL and keep increasing the intensity. minFront, maxFront, minBack and maxBack are ellipses and by juggling around with them you can determine the reach of a particular sound. We'll explain all of this at a later date.

(((((((((((((((((((((( SURROUND SOUND ))))))))))))))))))))))

Now that you've seen what you can do with RSX, ask what RSX can do for you. Like, who's going to use all this code ?

For years now, people have harped about the attention grabbing features of and user-friendliness of Multimedia. It's been over-hyped and over-marketed, yet we saw no concrete implementation of it in an application. After all, I don't want multimedia as a separate package, I want to incorporate it into my applications. I want my C/C++, PowerBuilder, Visual Basic or any other Windows95 products to have animation and most importantly, sound. For years there was now easy way to do either, but now, using RSX, which is presently an OCX, ( but which will soon be converted into an ActiveX Object ), I can add sound to my product. Not only that, I can now add realistic sound to my HTML or VRML pages !! RSX paves the way for Windows95 applications that talk back to you !.

There are Java classes that can do the same thing, but unfortunately, Java cannot be integrated into most existing applications. That's the major obstacle in working with Java. I can do amazing things with it, but I can't use it in PowerBuilder, or Visual Basic for that matter. On the other hand, RSX, today an OCX, by tomorrow an ActiveX Object, will open up a whole new world of opportunity as it bulldozes a path to programming nirvana.

Now you might say that the same job could have been done using the sndPlaySound function in mmsystem.h. Why use an OCX? Well, if you've used .dll's before, you know that working with them has it's irritations. When you use a .dll file, its functions are indirect and separate. One function doesn't have any knowledge about the other. On the other hand, an OCX is a live entity, which is conscious of it's various organs. That is the basic difference between using an OCX and using .dll's. With OCX's , it's like having a whole application come to you and not just disparate functions.

All our teaching examples are extremely simple and uncomplicated, but we could have gone gung-ho over this new technology. We could have created a house, with a garden full of twittering birds on the outside and a blaring TV on the inside. The house could have had multiple rooms, with multiple sounds encompassed within each. If we had done so, you would have gotten so lost figuring out the graphics code that the basic logic would have escaped you.

Now the nice thing about Intel is that they have gone one step further, they have given us an .exe file called SoundTracker, with which we can test their product. Run the program and check it out !

One of the many menu option present is Load Bitmap. Using this, load any bitmap unto the screen. To add sound to the picture, click on the image with the right mouse button and then click Add Sound. Use any .wav file that you desire and set its volume. It's possible (and recommended) to have more than one .wav file playing at a time, so add as many as you want. Next click on Play sound and be amazed. As your mouse pointer moves from one section of the screen to another, the volume of the different sounds change, as they mix and merge together. More importantly, you can ask the program to Show you the sound sources and you can even drag them about. When Show is check marked, each of the sound sources are surrounded by two ellipses. One has a thicker border and smaller area and if your pointer ventures there you hear the wav file in all its splendor. As you leave the inner ellipse and migrate towards the outer, thinner one, the sound gradually fades away. When there are a half a dozen emitters, the effect is quite simply, electric.

Click Save and your image, along with its accompanying sounds will be saved as a .wrl file. Unfortunately, not to many other browsers fully understand RSX, but the biggie ( Netscape )does, so it won't be long before it's a standard feature.

When your mind goes blank, turn off the sound ....

By now, you've probably thought up a dozen or more new uses for this technology. For example, I can now introduce new types of warnings into my product, making it virtually idiot proof. Depending on where the users mouse is, I can have the application giving helpful tips or warning him about potential pitfalls. I can now have graphs that talk back and games that communicate with the player. Or how about a windows shell for the visually impaired. The creative and business possibilities are almost endless.

Programming, will never be the same again.


This tutorial is a joint effort of
Mr. Vijay Mukhi
Ms. Sonal Kotecha
Mr. Arsalan Zaidi


Have any suggestions, comments, ideas, cracked code, feed back ? Feel free to let us know .

Want to be in touch with still more latest technologies? Visit VIJAY MUKHI'S TECHNOLOGY CORNUCOPIA .


Vijay Mukhi's Computer Institute
B-13, Everest Building, Tardeo, Mumbai 400 034, India.
http://www.vijaymukhi.com
e-mail :vmukhi@giasbm01.vsnl.net.in
Tel : 91-22-496 4335 /6/7/9
Fax : 91-22-307 28 59