Skip to main content
gamedev.net
🔒 Locked

errors in building project

Started by spirit0306 2 replies 2k views
Original Post
spirit0306
spirit0306
Hi! I am attemting to capture sound directly from a mic with direcsound. But i am receiving errors such as: error LNK2001: unresolved external symbol _DXTraceA@20 error LNK2001: unresolved external symbol "public: __thiscall CWaveFile::~CWaveFile(void)" (??1CWaveFile@@QAE@XZ) error LNK2001: unresolved external symbol "public: long __thiscall CWaveFile::Write(unsigned int,unsigned char *,unsigned int *)" (?Write@CWaveFile@@QAEJIPAEPAI@Z) fatal error LNK1120: 3 unresolved externals How can I resolve these errors? I do not know what to do... here is my code:


// CaptureSound.cpp : Defines the entry point for the application.
//
#define STRICT
#include <windows.h>
#include <basetsd.h>
#include <commdlg.h>
#include <mmreg.h>
#include <dxerr9.h>
#include <dsound.h>
#include "resource.h"
#include "DSUtil.h"
#include "DXUtil.h"

//-----------------------------------------------------------------------------
// Function-prototypes
//-----------------------------------------------------------------------------

HRESULT INITDIRECTSOUND( HWND hDlg, GUID* pDeviceGuid );
HRESULT CreateCaptureBuffer( WAVEFORMATEX* pwfxInput );
HRESULT InitNotifications();
HRESULT StartOrStopRecord(BOOL bStartRecording);
HRESULT RecordCapturedData() ;
HRESULT OnSaveSoundFile( HWND hDlg ); 
HRESULT FreeDirectSound();
HRESULT OnInitMainDialog( HWND hDlg );
HRESULT OnInitMainDialog( HWND hDlg );INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );

//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define NUM_REC_NOTIFICATIONS  16
#define MAX(a,b)        ( (a) > (b) ? (a) : (b) )
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

LPDIRECTSOUNDCAPTURE dsCapture        = NULL;
DSBPOSITIONNOTIFY          pPosNotify[ NUM_REC_NOTIFICATIONS + 1 ];
LPDIRECTSOUNDCAPTUREBUFFER g_pDSBCapture        = NULL;
DWORD                      g_dwCaptureBufferSize;
LPDIRECTSOUNDNOTIFY        lpDSBNotify          = NULL;
LPDIRECTSOUNDNOTIFY        g_pDSNotify          = NULL;
HANDLE                     g_hNotificationEvent;
DWORD                      g_dwNotifySize;
DWORD                      g_dwNextCaptureOffset;
HINSTANCE                  g_hInst              = NULL;
GUID                       g_guidCaptureDevice  = GUID_NULL;
BOOL                       g_bRecording;
CWaveFile*                  g_pWaveFile;


//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point for the application.  Since we use a simple dialog for 
//       user interaction we don't need to pump messages.
//-----------------------------------------------------------------------------
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, 
                      INT nCmdShow )
{	HRESULT hr;
    DWORD dwResult;
    MSG   msg;
    BOOL  bDone;
    HWND  hDlg;

    g_hInst = hInst;
    g_hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

    // Display the main dialog box.
    dwResult = DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );


	if( dwResult != IDOK )
    {
        // The user canceled, so stop message pump, 
        // and fall through to the cleanup code
        PostQuitMessage( 0 );
    }
    else
    {
        // Init DirectSound
        if( FAILED( hr = INITDIRECTSOUND( hDlg, &g_guidCaptureDevice ) ) )
        {
            DXTRACE_ERR_MSGBOX( TEXT("InitDirectSound"), hr );
            MessageBox( hDlg, "Error initializing DirectSound.  Sample will now exit.", 
                        "DirectSound Sample", MB_OK | MB_ICONERROR );
            PostQuitMessage( 0 );
            dwResult = IDCANCEL;
        }
	}

	bDone = FALSE;
    while( !bDone ) 
    { 
        dwResult = MsgWaitForMultipleObjects( 1, &g_hNotificationEvent, 
                                              FALSE, INFINITE, QS_ALLEVENTS );
        switch( dwResult )
        {
            case WAIT_OBJECT_0 + 0:
                // g_hNotificationEvents[0] is signaled

                // This means that DirectSound just finished playing 
                // a piece of the buffer, so we need to fill the circular 
                // buffer with new sound from the wav file

                if( FAILED( hr = RecordCapturedData() ) )
                {
                    DXTRACE_ERR_MSGBOX( TEXT("RecordCapturedData"), hr );
                    MessageBox( hDlg, "Error handling DirectSound notifications. "
                               "Sample will now exit.", "DirectSound Sample", 
                               MB_OK | MB_ICONERROR );
                    bDone = TRUE;
                }
                break;

            case WAIT_OBJECT_0 + 1:
                // Windows messages are available
                while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) 
                { 
                    if( !IsDialogMessage( hDlg, &msg ) )  
                    {
                        TranslateMessage( &msg ); 
                        DispatchMessage( &msg ); 
                    }

                    if( msg.message == WM_QUIT )
                        bDone = TRUE;
                }
                break;
        }
    }
	StartOrStopRecord( FALSE );

    // Clean up everything
    FreeDirectSound();

    CloseHandle( g_hNotificationEvent );

    return TRUE;
}

//-----------------------------------------------------------------------------
// Name: OnInitDialog()
// Desc: Initializes the dialogs (sets up UI controls, etc.)
//-----------------------------------------------------------------------------
HRESULT OnInitMainDialog( HWND hDlg )
{
    //HRESULT hr;

    EnableWindow( GetDlgItem( hDlg, IDC_RECORD ), FALSE);
//    SetDlgItemText( hDlg, IDC_FILENAME, TEXT("No file loaded.") );

    return S_OK;

}

//-----------------------------------------------------------------------------
// Name: MainDlgProc()
// Desc: Handles dialog messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
    HRESULT hr;

    switch( msg ) 
    {
    case WM_INITDIALOG:
        OnInitMainDialog( hDlg );
        break;

    case WM_COMMAND:
        switch( LOWORD(wParam) )
        {
            case IDCANCEL:
                PostQuitMessage( 0 );
                EndDialog( hDlg, IDCANCEL );
                break; 

            case IDC_SOUNDFILE:
                OnSaveSoundFile( hDlg );
                break;

            case IDC_RECORD:
                g_bRecording = !g_bRecording;
                if( FAILED( hr = StartOrStopRecord( g_bRecording ) ) )
                {
                    DXTRACE_ERR_MSGBOX( TEXT("StartOrStopRecord"), hr );
                    MessageBox( hDlg, "Error with DirectSoundCapture buffer."                            
                                "Sample will now exit.", "DirectSound Sample", 
                                MB_OK | MB_ICONERROR );
                    PostQuitMessage( 0 );
                    EndDialog( hDlg, IDABORT );
                }

               if( !g_bRecording )
                   EnableWindow( GetDlgItem( hDlg, IDC_RECORD ), FALSE );

                break;

            

            default:
                return FALSE; // Didn't handle message
        }
        break;

    default:
        return FALSE; // Didn't handle message
    }

    return TRUE; // Handled message
}



HRESULT INITDIRECTSOUND( HWND hDlg, GUID* pDeviceGuid )

{

     HRESULT hr;
	 ZeroMemory( &pPosNotify, sizeof(DSBPOSITIONNOTIFY) * 
                               (NUM_REC_NOTIFICATIONS + 1) );
	 dsCapture=NULL;
	 g_dwCaptureBufferSize = 0;
	 g_dwNotifySize        = 0;
	 g_pWaveFile           = NULL;

	 hr = CoInitialize(NULL);
	 hr = DirectSoundCaptureCreate(NULL,&dsCapture,NULL);
	 return IDOK;

}

HRESULT FreeDirectSound()

{
    SAFE_DELETE( g_pWaveFile );

    // Release DirectSound interfaces
    SAFE_RELEASE( g_pDSNotify );
    SAFE_RELEASE( g_pDSBCapture );
    SAFE_RELEASE( dsCapture ); 

    // Release COM
    CoUninitialize();

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: OnSaveSoundFile()
// Desc: Called when the user requests to save to a sound file
//-----------------------------------------------------------------------------
HRESULT OnSaveSoundFile( HWND hDlg ) 
{
    HRESULT hr;

    static TCHAR strFileName[MAX_PATH] = TEXT("");
    static TCHAR strPath[MAX_PATH] = TEXT("");

    // Setup the OPENFILENAME structure
    OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
                         TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
                         0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
                         TEXT("Save Sound File"),
                         OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | 
                         OFN_HIDEREADONLY    | OFN_NOREADONLYRETURN, 
                         0, 0, TEXT(".wav"), 0, NULL, NULL };

    // Get the default media path (something like C:\WINDOWS\MEDIA)
    if( '\0' == strPath[0] )
    {
        if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 )
        {
            if( strcmp( &strPath[strlen(strPath)], TEXT("\\") ) )
                strcat( strPath, TEXT("\\") );
            strcat( strPath, TEXT("MEDIA") );
        }
    }

    if( g_bRecording )
    {
        // Stop the capture and read any data that 
        // was not caught by a notification
        StartOrStopRecord( FALSE );
        g_bRecording = FALSE;
    }

   /* // Update the UI controls to show the sound as loading a file
    EnableWindow( GetDlgItem( hDlg, IDC_RECORD ), FALSE );
    SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Saving file...") );

    SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );

    SAFE_DELETE( g_pWaveFile );
    g_pWaveFile = new CWaveFile;
    if( NULL == g_pWaveFile )*/
        return IDOK;
}


HRESULT CreateCaptureBuffer( WAVEFORMATEX* pwfxInput )

{

WAVEFORMATEX wave; 
ZeroMemory(&wave,sizeof(WAVEFORMATEX));
wave.wFormatTag = WAVE_FORMAT_PCM;
wave.nChannels = 2; 
wave.nSamplesPerSec= 44100; 
wave.nAvgBytesPerSec = 44100 * 4; 
wave.nBlockAlign = 4; 
wave.wBitsPerSample = 16; 
wave.cbSize = 0; 

	SAFE_RELEASE( g_pDSNotify );
    SAFE_RELEASE( g_pDSBCapture );

    // Set the notification size
    g_dwNotifySize = MAX( 1024, pwfxInput->nAvgBytesPerSec / 8 );
    g_dwNotifySize -= g_dwNotifySize % pwfxInput->nBlockAlign;   

    // Set the buffer sizes 
    g_dwCaptureBufferSize = g_dwNotifySize * NUM_REC_NOTIFICATIONS;

    SAFE_RELEASE( g_pDSNotify );
    SAFE_RELEASE( g_pDSBCapture );

	
	HRESULT hr;
    DSCBUFFERDESC dscbd;
	WAVEFORMATEX w;
	// Create the capture buffer
    ZeroMemory( &dscbd, sizeof(dscbd) );
    dscbd.dwSize        = sizeof(dscbd);
	dscbd.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY;
    dscbd.dwBufferBytes = g_dwCaptureBufferSize;
    dscbd.lpwfxFormat   = pwfxInput; // Set the format during creatation

    if( FAILED( hr = dsCapture->CreateCaptureBuffer( &dscbd, 
                                                        &g_pDSBCapture, 
                                                        NULL ) ) )
        return IDOK;
}

HRESULT InitNotifications()
{
	HRESULT hr;
	
	//Set Direct Sound Buffer Notify Position
	//g_hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
	
	if( FAILED( hr = g_pDSBCapture->QueryInterface( IID_IDirectSoundNotify, 
                                                    (VOID**)&g_pDSNotify ) ) )

	return IDOK;

	for( INT i = 0; i < NUM_REC_NOTIFICATIONS; i++ )
    {
        pPosNotify.dwOffset = (g_dwNotifySize * i) + g_dwNotifySize - 1;
        pPosNotify.hEventNotify = g_hNotificationEvent;             
    }

	

	if ( FAILED(lpDSBNotify->SetNotificationPositions(NUM_REC_NOTIFICATIONS, pPosNotify)) ) 
		
		return DXTRACE_ERR_MSGBOX( TEXT("SetNotificationPositions"), hr );
	


	
}

HRESULT StartOrStopRecord(BOOL bStartRecording)
{
	HRESULT hr;

    if( bStartRecording )
    {
        
        
        if( FAILED( hr = g_pDSBCapture->Start( DSCBSTART_LOOPING ) ) )

			return IDOK;
            
    }
    else
    {
        

        // Stop the buffer, 
        if( FAILED( hr = g_pDSBCapture->Stop() ) )
            
	return IDOK;
	}

}

HRESULT RecordCapturedData() 

{
	HRESULT hr;
    VOID*   pbCaptureData    = NULL;
    DWORD   dwCaptureLength;
    VOID*   pbCaptureData2   = NULL;
    DWORD   dwCaptureLength2;
    DWORD   dwReadPos;
	UINT    dwDataWrote;
    DWORD   dwCapturePos;
    LONG lLockSize;
//	void* audio1=NULL,*audio2=NULL;
//	void* buf;

	if( NULL == g_pDSBCapture )
        return S_FALSE;
    if( NULL == g_pWaveFile )
        return S_FALSE;

	if( FAILED( hr = g_pDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("GetCurrentPosition"), hr );

    lLockSize = dwReadPos - g_dwNextCaptureOffset;
    if( lLockSize < 0 )
        lLockSize += g_dwCaptureBufferSize;

    // Block align lock size so that we are always write on a boundary
    lLockSize -= (lLockSize % g_dwNotifySize);

    if( lLockSize == 0 )
        return S_FALSE;

    // Lock the capture buffer down
    if( FAILED( hr = g_pDSBCapture->Lock( g_dwNextCaptureOffset, lLockSize, 
                                          &pbCaptureData, &dwCaptureLength, 
                                          &pbCaptureData2, &dwCaptureLength2, 0L ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr );

    // Write the data into the wav file
    if( FAILED( hr = g_pWaveFile->Write( dwCaptureLength, 
                                              (BYTE*)pbCaptureData, 
                                              &dwDataWrote ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("Write"), hr );

    // Move the capture offset along
    g_dwNextCaptureOffset += dwCaptureLength; 
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer

    if( pbCaptureData2 != NULL )
    {
        // Write the data into the wav file
        if( FAILED( hr = g_pWaveFile->Write( dwCaptureLength2, 
                                                  (BYTE*)pbCaptureData2, 
                                                  &dwDataWrote ) ) )
            return DXTRACE_ERR_MSGBOX( TEXT("Write"), hr );

        // Move the capture offset along
        g_dwNextCaptureOffset += dwCaptureLength2; 
        g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer
    }

    // Unlock the capture buffer
    g_pDSBCapture->Unlock( pbCaptureData,  dwCaptureLength, 
                           pbCaptureData2, dwCaptureLength2 );


    return S_OK;
	

/*if( FAILED( hr = g_pDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos ) ) )

g_pDSBCapture->Lock( g_dwNextCaptureOffset, lLockSize, 
                                          &pbCaptureData, &dwCaptureLength, 
                                          &pbCaptureData2, &dwCaptureLength2, 0L);

if(audio1) memcpy(buf,pbCaptureData,dwCaptureLength);
if(audio2) memcpy((char*)buf+dwCaptureLength,pbCaptureData2,dwCaptureLength2);

g_pDSBCapture->Unlock( pbCaptureData,  dwCaptureLength, 
                           pbCaptureData2, dwCaptureLength2 );



	return IDOK;*/
}
[/source}









Paulius Maruska
Paulius Maruska
For DXTrace to work, you need to add Dxerr.lib library to your projects dependencies.
As for CWaveFile - it looks like it's a class from DX samples that comes with DXSDK. You should add (SDK root)\samples\C++\Common\DXUTsound.h and (SDK root)\samples\C++\Common\DXUTsound.cpp to your project.

That's all I could find on MSDN. Hope this helps.
spirit0306
spirit0306
Thanks! I have resolved 1 error which is with the DXtrace... But I cannot resolve the other 2. I cannot find any "(SDK root)\samples\C++\Common\DXUTsound.h and (SDK root)\samples\C++\Common\DXUTsound.cpp" in my directx folder. Are there any alternative names for these?

The errors are the same:

error LNK2001: unresolved external symbol "public: __thiscall CWaveFile::~CWaveFile(void)" (??1CWaveFile@@QAE@XZ)

error LNK2001: unresolved external symbol "public: long __thiscall CWaveFile::Write(unsigned int,unsigned char *,unsigned int *)" (?Write@CWaveFile@@QAEJIPAEPAI@Z)
Paulius Maruska
Paulius Maruska
The fact that you have linker errors and not compiler errors tells that you already have the header file included properly. I'd look for the cpp file in the same directory where this header file is located.

Oh, and in case you don't know where are all those includes - you can turn on the compiler switch that will print all included files to you (/showIncludes).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.