Click here to Skip to main content
15,881,709 members
Articles / Desktop Programming / MFC

SDI (Sound Device Interface)--A library for Auditory Display

Rate me:
Please Sign up or sign in to vote.
4.60/5 (3 votes)
2 May 20046 min read 110.2K   3.7K   45  
A GDI-like API for 3D positioning of speech, and MIDI composition using a single string.
// TestSDIdll.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "sdi.h"
#include <crtdbg.h>

#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	BOOL br;
	int i=0;
	SDIVECTOR pos={0,0,0};

	// Initialize SDI Environment
 	br=InitializeSDI(NULL, NULL, hInstance, 0);
	_ASSERTE(br);
	
	// Create a guild
	HSPEECH hGuide=CreateSpeech(SDI_LANGUAGE_GENERAL_AMERICAN_ENGLISH, 
									SDI_VOICE_ADULTMALE1, 0);
	Sleep(1000);	// At present, some delay is highly recommanded

	// Set position
	pos.x=1.0f;	// positioned at the right
	pos.z=1.0f;
	br=SetPosition(hGuide, &pos);

	PlayText(hGuide, "Hello, world.");
	Sleep(2000);

	/////////////////////////////////////////////////////////////////
	// Test 1: Earcon Object

	// Subtest 1: Test playing track (from MIDI file)
	HEARCON hEarcon1=CreateEarcon(666666L, 1024, 	// Get tempo info from MIDI file
		MAKE_TIMESIGNATURE(4,2,0x18,0x08),MAKE_KEYSIGNATURE(0,0));

	// Load track data
	HRSRC hRes=FindResource(hInstance,MAKEINTRESOURCE(IDR_COMEACROSS),"MIDI");
	_ASSERTE(hRes);
	HGLOBAL hGlobal=LoadResource(hInstance,hRes);
	_ASSERTE(hGlobal);
	BYTE* pRes=(BYTE*)LockResource(hGlobal);
	_ASSERTE(pRes);

	// Set position
	pos.x=1.0f;
	pos.z=1.0f;
	br=SetPosition(hEarcon1, &pos);

	// Select Instrument, you can change the instrument as you like
	//                                  ��change it
	br=SetChannelInstrument(hEarcon1, 0, 0, NULL);	// channel 0: Acoustic Grand Piano

	BYTE* pData[1]={pRes};	// 1 track. You can add as many as 16 tracks if you like.

	PlayText(hGuide, "This music is positioned on your right.");
	Sleep(3000);

	br=PlaySegment(hEarcon1, pData,1);
	Sleep(4000);

	pos.x=-1.0f;
	SetPosition(hEarcon1, &pos); // You can experience the positioning of Earcon.
	                             // You can compare it with following Speech object.
	Sleep(4000);

	// Turn down the volume
	for(i=10; i>3; i--)
	{
		SetVolume(hEarcon1, (FLOAT)i/20+0.6f);
		Sleep(200);
	}

	// Subtest 2: Test playing music notation
	HEARCON hEarcon2=CreateEarcon(600000L, 480, MAKE_TIMESIGNATURE(6,3,0,0),0);
	
	pos.x=-1.0f;
	pos.z=0;
	br=SetPosition(hEarcon2, &pos);
	// Compose some music measures
	PTSTR psNotation=
		"@I00 E42 E42 F42 G42 G42 F42 E42 D42 C42 C42 D42 E42 E42. D43 D41;"
		"@I34 E40 G40 C40 E40";
	
	PlayText(hGuide, "The following Carol is composed using text string.");
	Sleep(3000);

	br=PlayNotation(hEarcon2, psNotation);
	Sleep(10000);

	// Subtest 3: Test parse music notation, and export it to a midi file
	BYTE* data;

	// First, get the buffer size required
	int  nLen=ParseNotation(hEarcon2, 
		"@I00 E42 E42 F42 G42 G42 F42 E42 D42 C42 C42 D42 E42 E42. D43 D41;"
		"@I34 E40 G40 C40 E40", 
		NULL);	
	data=new BYTE[nLen];
	_ASSERTE(data);
	
	// Fill the buffer
	ParseNotation(hEarcon2, 
		"@I00 E42 E42 F42 G42 G42 F42 E42 D42 C42 C42 D42 E42 E42. D43 D41;"
		"@I34 E40 G40 C40 E40",
		data);	
	
	PlayText(hGuide, "The previously composed Carol is being output to a MIDI file.");
	Sleep(3000);

	// Write to a file
	HANDLE hFile=CreateFile("test.mid", GENERIC_READ|GENERIC_WRITE, 0,
					NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	_ASSERTE(hFile!=INVALID_HANDLE_VALUE);
	DWORD dwWritten;
	WriteFile(hFile, data, nLen, &dwWritten, NULL);

	CloseHandle(hFile);
	delete[] data;

	Sleep(3000);

	// Delete Earcon Object
	// DeleteSDIObject(hEarcon1);  // Leave it to ReleaseSDI()
	//DeleteSDIObject(hEarcon2);	

	/////////////////////////////////////////////////////////////////
	// Test 2 : Speech Object
	HSPEECH hSpeech1=CreateSpeech(SDI_LANGUAGE_GENERAL_AMERICAN_ENGLISH, 
									SDI_VOICE_ADULTMALE2, 0);
	Sleep(1000);	// At present, some delay is highly recommanded

	// Set position
	pos.x=-1.0f;	// positioned at the left
	pos.z=0;
	br=SetPosition(hSpeech1, &pos);

	PlayText(hGuide, "The following test demonstrates various use of Speech object.");
	Sleep(3000);

	// Play a sentence.
	br=PlayText(hSpeech1, "The sound is coming from the left. ");
	Sleep(1000);
	
	// Add a sentence.
	br=AddText(hSpeech1, "This sentence is appended to the end of the sentence list. "
						 "And it will be played after the previous sentence.");
	Sleep(1000);

	// To test the robustness
	Pause(hSpeech1);
	Sleep(1000);
	Play(hSpeech1);  // no text in queue
	Sleep(1000);

	PlayText(hGuide, "A sound animation demo.");
	Sleep(3000);

	// Play another sentence
	br=PlayText(hSpeech1, "This sentence replaced the previous one. "
					"You can feel it as it moves from the left to the right.");

	// Move the speech object from left to right, and turn down the volume a little bit
	for(i=-20; i<20; i++)
	{
		SDIVECTOR animation={(FLOAT)i/20, 0, 1.0f};
		// the positioning of Speech is much better than Earcon
		SetPosition(hSpeech1, &animation);	
		Sleep(100);
	}
	SetVolume(hSpeech1, 0.4f);

	// Start another Speech Objects
	HSPEECH hSpeech2=CreateSpeech(SDI_LANGUAGE_GENERAL_AMERICAN_ENGLISH, 
		                          SDI_VOICE_ADULTFEMALE1, 0);
	pos.x=-1.0f;
	pos.z=0;
	SetPosition(hSpeech2, &pos);

	// You can feel two sound sources coming from different direction
	PlayText(hSpeech2, "Everything is possible--Li Ling");	
	Sleep(5000);

	// Delete speech object
	DeleteSDIObject(hSpeech1);
	// DeleteSDIObject(hSpeech2);	// Leave it to ReleaseSDI()

	// To test the robustness of sound object.
	// hSpeech1 has been deleted previously
	PlayText(hSpeech1,"This is the end of test. Enjoy the SDI!");

	PlayText(hSpeech2,"This is the end of test. Enjoy the SDI!");
	Sleep(20000);
	// Release SDI Environment when you left.
	ReleaseSDI();	// Traverse the object list to delete hSpeech2 and hEarcon2

	return 0;
}



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer
China China
A student at Zhejiang University, Zhejiang, China.
Major in Automation.
Now I want to study machine vision and robotics, but I'm really consumed with choices between hardware and software, and between research and engineering.
I'll be glad if you can give some suggestions.

Comments and Discussions