Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

how to set output device

Posted on 2001-06-15
12
Medium Priority
?
742 Views
Last Modified: 2013-11-20
Dear Experts

We have to set phone line as our output device for the playback of a wave file ? we r unable to get hang on it.our tool is Visual C++
And we also donot know how to get device identifier,,

Thanx

Bye

trium
0
Comment
Question by:trium
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 32

Expert Comment

by:jhance
ID: 6196182
This question is about as ambiguous as I've seen.

Some details about what you are doing would really help...
0
 
LVL 3

Accepted Solution

by:
JackThornton earned 400 total points
ID: 6197445
You need to use the TAPI (Microsoft Telephony API). Documentation can be found in MSDN, even on-line.

Note that modems, even "voice modems", do not necessarily implement TAPI or true telephony features fully or correctly.

To get a device identifier, you need to open a line device with lineOpen - this will give you a handle to the line. The device ID's you give to lineOpen will be fairly linear indices (e.g. if you have a device with 4 lines, the indices will be 0-3).

Getting the device ID is only tricky because of an ill-considered use of VARSTRING structure. Code to fetch the ID:

unsigned
Line::GetDeviceID(HLINE hLine, LPCTSTR deviceName)
{
DevIdVarString devID;

    // initialize a VARSTRING structure
    devID.dwTotalSize = sizeof(DevIdVarString);
    devID.dwNeededSize = 0;
    devID.dwUsedSize = 0;
    devID.dwStringFormat = STRINGFORMAT_BINARY;
    devID.dwStringSize = 0;
    devID.dwStringOffset = 0;

    // get the device identifier from TAPI
    if (lineGetID(hLine, 0, 0, LINECALLSELECT_LINE, &devID, deviceName) != 0)
        throw 0;

    // return the discovered value
    _ASSERT(devID.dwStringFormat == STRINGFORMAT_BINARY);
    return *((DWORD *)(((BYTE *)&devID)+devID.dwStringOffset));

where deviceName would, for your purposes, be "wave/out".

Hope this helps.
   
   
0
 

Author Comment

by:trium
ID: 6242863

Dear jack

i used the function lineGetID to get the device identifire so that
phone could be used as an output device to play the sound file.


LPCSTR deviceName="wave/out";

VARSTRING devID;

LONG retcode;
   // initialize a VARSTRING structure
   devID.dwTotalSize = sizeof(VARSTRING);
   devID.dwNeededSize = 0;
   devID.dwUsedSize = 0;
   devID.dwStringFormat = STRINGFORMAT_BINARY;
   devID.dwStringSize = 0;
   devID.dwStringOffset = 0;


lineGetID(hLine, 0, hCall, LINECALLSELECT_LINE, &devID, deviceName) ;



ASSERT(devID.dwStringFormat == STRINGFORMAT_BINARY);
   retcode= *((DWORD *)(((BYTE *)&devID)+devID.dwStringOffset));


the value i got at "retcode" is 24 which i think is the device identifire
of the opened line.then i passed this value to "waveOutOpen" function to
open the outputdevice(phone).


  LPHWAVEOUT phwo;          
  UINT uDeviceID=retcode1;            
  LPWAVEFORMATEX pwfx;
  DWORD dwCallback;      
  DWORD dwCallbackInstance;
  DWORD fdwOpen ;
     
 waveOutOpen(
            phwo,          
            uDeviceID,  
            pwfx,      
            dwCallback,          
            dwCallbackInstance,  
            fdwOpen              
            );
and then used "PlaySound" function to play the sound file.




LPCSTR pszSound ="filename.wav;
HMODULE hmod =NULL;
  DWORD fdwSound  =SND_FILENAME;
     

PlaySound(
          pszSound,  
          hmod,    
          fdwSound    
          );

but still the sound file is  played on the speaker not on the phone.
plz tell me what should i do so that phone is set as the output device
to play the sound file.

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 3

Expert Comment

by:JackThornton
ID: 6250368
You cannot use the easy "PlaySound" to accomplish this. You need to use the waveform API directly (in this case, the waveOutXXXX calls). You will need to open a waveout device. You will then need to load the contents of the file into a RAM buffer (or, if it is a really large file, you will need to load and play the file in portions, which takes a little more code), build a WAVEHDR structure pointing to your buffer, and submit the WAVEHDR to waveOutWrite.

For more points, I will be happy to post or email you some working sample code for playing audio data using the waveOut functions (in fact, code that was used to output to phone lines using TAPI, although the output device is irrelevant).

- jack
0
 

Author Comment

by:trium
ID: 6260528
Now that the points are increased, u must send me proper working code.
Its in your favour if u wanna get all marks,......!

trium
0
 
LVL 3

Expert Comment

by:JackThornton
ID: 6270947
Pick up the code at:

http://www.cetasoft.com/JackThornton/code/omsrc.zip

This contains some production code of a more elaborate system than you probably need. The main file of interest is AudioDevice.cpp (the "speaker" section). It will demonstrate how to prepare a wave header for an audio buffer and submit that header (with a pointer to the buffer) to be played by the wave output API. It also demonstrates how to receive notification that the buffer has been played (or at least output to the hardware; if the audio hardware has a significant chunk of on-board RAM buffer or other latency problems then it is possible that you might get the notification before the sound has actually finished playing). You can queue up multiple buffers to be played, which makes it easy to string together different bits and pieces of audio.

Some of the code contains automatic conversion between PCM and muLaw - you can pull this code out.

Be particularly mindful of the formats the output device actually supports - you can call waveOutOpen in a way that will query for support of a particular format without actually opening the device.

You will not be able to use the classes as-is, but there is much code to study and bits and pieces you can cut and paste.

I've also included the Line source files to show how I opened the line device and got my "handle" to the waveout audio device.

Hope this helps.

- jack
0
 

Author Comment

by:trium
ID: 6335898
dear jack
thanx alot for your code.i've tried that but stucked at a point
which is the first parameter of WAVEHDR structure
LPSTR lpData // pointer to the waveform buffer.
plz guide me how to pass the waveform buffer.
0
 
LVL 3

Expert Comment

by:JackThornton
ID: 6341619
The waveform buffer is the raw waveform data, WITHOUT the header or any other information. For example, if you load in a standard .WAV file, the waveform data will be encapsulated inside the "data" chunk. Examine the method AudioBuffer::GetWaveData in AudioBuffer.cpp to see how to pull the data out of a WAV file, if this is what you're stuck at.

Once you have a block of waveform data, simply pass a pointer to that data in lpData. Ignore the fact that the type is LPSTR, this is old Microsoft code back before they became more intelligent about designing API's (they should have used "LPVOID"; "BYTE *" would have been acceptable; using "LPSTR" is lazy and misleading, which is very bad policy for an API meant for others to use). Just use either a standard 'C' style cast or a C++ reinterpret_cast to cast the pointer to the beginning of the waveform data to LPSTR.

- jack
0
 

Author Comment

by:trium
ID: 6394734
Dear jack

Thanx 4 ur guidance.i used the function GetWaveData() and tried to set the lpData parameter

here is the code

// after successfully gettin' the devise ID

//open line device;
     HWAVEOUT phwo;
     

  LPWAVEFORMATEX pwfx;
  DWORD dwCallback=0;      
  DWORD dwCallbackInstance;
  DWORD fdwOpen=CALLBACK_NULL ;  
 
//--------------------------------  

 waveOutOpen(
 &phwo,          
 uDeviceID, //got it by lineGetID function  


 pwfx,      
  dwCallback,          
 dwCallbackInstance,  
  fdwOpen              
);
 //---------------------------------------

unsigned x;
void *src ="myfile.wav";
   

    unsigned wholeChunkSize = ((DWORD *)src)[1];
     unsigned fileSize = wholeChunkSize + 8;  
     BYTE *pFormatChunk = (BYTE *)src + 8;
     ++pFormatChunk;

WAVEFORMATEX *pFormat = (WAVEFORMATEX *) (pFormatChunk + 12);
     unsigned formatSize = ((DWORD *)pFormatChunk)[2];

BYTE *pDataChunk = (BYTE *)src + 8;

++pDataChunk;

void *pData = (void *) (pDataChunk + 8);
unsigned dataSize = ((DWORD *)pDataChunk)[1];



HWAVEOUT hwo=phwo;
  WAVEHDR *pwh;
pwh->lpData=(LPSTR)pData;  
pwh->dwBufferLength=dataSize;
pwh->dwBufferLength=0;
pwh->dwFlags=0;
pwh->dwLoops=0;
pwh->dwUser=0;
pwh->lpNext=0;
pwh->reserved=0;

//-------------------------------------
  UINT cbwh;
 waveOutPrepareHeader(
  hwo,  
   pwh,
   cbwh      
);

//------------------------------
 waveOutWrite(
  hwo,  
   pwh,
   cbwh      
);

//--------------------------------------

The code is without error checking.ignore this.
kindly point out my mistakes and how can i make them correct. Don't worry about the points. if i get my problem solved, i'll give u all
of my points 'cuz i need it to be solved as soon as possible.
0
 
LVL 3

Expert Comment

by:JackThornton
ID: 6394788
Could you tell me what errors you're having running this code before I take a look at it?

thanx

- jack
0
 

Author Comment

by:trium
ID: 6398891
......no error....but i cannot hear my sound file being played on dialed telephone
0
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9490002
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered by : JackThornton

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

609 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question