F
Firefox
Здравствуйте. Создала отдельную программу для записи данных с микрофона. все работает и хорошо. далее понадобилось подключить классы этой программы в основную(большую) программу. в основной программе так же используется работа с DirectSound. но стало выдавать вот такие ошибки
error LNK2001: unresolved external symbol ___argc
error LNK2001: unresolved external symbol ___wargv
error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in msvcprtd.lib(newop_s.obj)
error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in msvcprtd.lib(newaop_s.obj)
error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in MSVCRTD.lib(MSVCR71D.dll)
вот код подключаемого класса:
если закоментировать функцию AfxBeginThread( WaitThreadProc1,this); ошибки пропадают. но тогда не функционирует класс. помогите пожалуйста.
error LNK2001: unresolved external symbol ___argc
error LNK2001: unresolved external symbol ___wargv
error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in msvcprtd.lib(newop_s.obj)
error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) already defined in msvcprtd.lib(newaop_s.obj)
error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in MSVCRTD.lib(MSVCR71D.dll)
вот код подключаемого класса:
C++:
///.h
#include <QtGui/QWidget>
#include <iostream>
#include <QMessageBox>
#include "Wavwrite.h"
#include <mmreg.h>
#include <dsound.h>
#include "initguid.h"
#include <QTextCodec>
#include <QFile>
#define NUM_REC_NOTIFICATIONS 16
class Mic_recod
{
public:
Mic_recod();
~Mic_recod();
LPDIRECTSOUNDCAPTURE g_pDSCapture;
LPDIRECTSOUNDCAPTUREBUFFER g_pDSBCapture;
LPDIRECTSOUNDNOTIFY g_pDSNotify;
LPTSTR strFileName1;
WAVEFORMATEX* g_pwfxInput;
DSBPOSITIONNOTIFY g_aPosNotify[ NUM_REC_NOTIFICATIONS + 1 ];
HANDLE g_hNotificationEvents[2];
BOOL g_abInputFormatSupported[16];
DWORD g_dwCaptureBufferSize;
DWORD g_dwNextCaptureOffset;
DWORD g_dwNotifySize;
bool g_bRecording;
CWaveSoundWrite* g_pWaveSoundWrite;
bool write_data_to_file(QString file_way);
void position_writing();
HRESULT StopBuffers();
HRESULT InitNotifications();
HRESULT CreateCaptureBuffer();
HRESULT RecordCapturedData();
private:
void Start_Func(bool g_bRecording);
};
//.cpp
#include "stdafx.h"
#include "Mic_record.h"
Mic_recod::Mic_recod()
{
g_pWaveSoundWrite= new CWaveSoundWrite();
ZeroMemory( &g_aPosNotify, sizeof(DSBPOSITIONNOTIFY) *
(NUM_REC_NOTIFICATIONS + 1) );
g_pDSCapture = NULL;
g_pDSBCapture = NULL;
g_pDSNotify = NULL;
g_pwfxInput = NULL;
g_dwCaptureBufferSize = 0;
g_dwNextCaptureOffset = 0;
g_dwNotifySize = 0;
g_pwfxInput= new WAVEFORMATEX;
g_pwfxInput->wFormatTag=WAVE_FORMAT_PCM;
g_pwfxInput->nSamplesPerSec = 44100;
g_pwfxInput->wBitsPerSample = 16;
g_pwfxInput->nChannels = 2;
g_pwfxInput->nBlockAlign = g_pwfxInput->nChannels * ( g_pwfxInput->wBitsPerSample >> 3 );
g_pwfxInput->nAvgBytesPerSec = g_pwfxInput->nBlockAlign * g_pwfxInput->nSamplesPerSec;
// Создание объекта IDirectSoundCapture для используемого устройства записи
if( FAILED( DirectSoundCaptureCreate( NULL, &g_pDSCapture, NULL ) ) )
throw;
g_hNotificationEvents[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
g_hNotificationEvents[1] = CreateEvent( NULL, FALSE, FALSE, NULL );
strFileName1=L"Sound1.wav";
g_pWaveSoundWrite->Open(strFileName1, g_pwfxInput);
}
Mic_recod::~Mic_recod()
{
// Уничтожение интерфейсов DirectSound
if( g_pDSNotify )
g_pDSNotify-> Release();
if( g_pDSBCapture )
g_pDSBCapture-> Release();
if( g_pDSCapture )
g_pDSCapture-> Release();
if( g_pWaveSoundWrite )
delete g_pWaveSoundWrite;
if( g_pwfxInput )
delete g_pwfxInput;
CloseHandle(g_hNotificationEvents[0]);
CloseHandle(g_hNotificationEvents[1]);
}
UINT WaitThreadProc1(LPVOID param)
{
Mic_recod* dlg = (Mic_recod*) param;
HANDLE* g_hNotificationEvents = dlg->g_hNotificationEvents;
DWORD dwResult;
while( dlg->g_bRecording )
{
dwResult =WaitForSingleObject(g_hNotificationEvents, INFINITE);
/*dwResult =MsgWaitForMultipleObjects( 2,g_hNotificationEvents,
FALSE, INFINITE, QS_ALLEVENTS );*/
if( dwResult == WAIT_OBJECT_0 )
{
// Отмечено событие g_hNotificationEvents[0]
// DirectSound только что записал очередной фрагмент аудио информации.
// Необходимо освободить циклический буфер и записать
// его содержимое в аудио файл
if( FAILED(dlg->RecordCapturedData()))
{
QMessageBox::warning(0,"error","Ошибка при работе с объектами извещений DirectSound. Приложение завершило свою работу.", "Использование DirectSound");
}
}
}
return 0;
}
void Mic_recod::Start_Func(bool g_bRecording)
{
if( g_bRecording==false)
{
// Останавливает запись и считывает несохранённую
// аудио информацию
StopBuffers();
}
else
{
if( FAILED(CreateCaptureBuffer()))
{
delete g_pWaveSoundWrite;
//delete g_pDSB_Record;
}
HRESULT hr;
hr=g_pDSBCapture->Start( DSCBSTART_LOOPING );
// Инициализация поцесса записи в буфер
if( hr==S_OK)
{
AfxBeginThread( WaitThreadProc1,this);
}
else
QMessageBox::warning( 0,"error","Ошибка при инициализации записи в буфер DirectSound.Приложение завершило свою работу.", "Использование DirectSound");
}
g_bRecording = !g_bRecording;
}
HRESULT Mic_recod::StopBuffers()
{
if( NULL == g_pDSBCapture )
return S_OK;
g_pDSBCapture-> Stop();
// Чтение информации из буфера записи
RecordCapturedData();
return S_OK;
}
HRESULT Mic_recod::RecordCapturedData()
{
HRESULT hr;
VOID* pbCaptureData = NULL;
DWORD dwCaptureLength;
VOID* pbCaptureData2 = NULL;
DWORD dwCaptureLength2;
VOID* pbPlayData = NULL;
UINT dwDataWrote;
DWORD dwReadPos;
DWORD dwCapturePos;
LONG lLockSize;
if( !g_pDSBCapture )
return S_FALSE;
if( !g_pWaveSoundWrite )
return S_FALSE;
if( FAILED( hr = g_pDSBCapture->GetCurrentPosition( &dwCapturePos, &dwReadPos ) ) )
return hr;
lLockSize = dwReadPos - g_dwNextCaptureOffset;
if( lLockSize < 0 )
lLockSize += g_dwCaptureBufferSize;
// Выравнивание границы блока
lLockSize -= (lLockSize % g_dwNotifySize);
if( lLockSize == 0 )
return S_FALSE;
/*char szRecordMsg[200];
sprintf( szRecordMsg, "Writing %5d bytes to file from capture buffer starting at offset %d\n", lLockSize, g_dwNextCaptureOffset );
OutputDebugString( szRecordMsg );*/
// Блокировка буфера записи
if( FAILED( hr = g_pDSBCapture->Lock( g_dwNextCaptureOffset, lLockSize,
&pbCaptureData, &dwCaptureLength,
&pbCaptureData2, &dwCaptureLength2, 0L ) ) )
return hr;
// Запись аудио информации в файл
if( FAILED( hr = g_pWaveSoundWrite->Write( dwCaptureLength,
(BYTE*)pbCaptureData,
&dwDataWrote ) ) )
return hr;
// Разблокирование буфера записи
g_pDSBCapture->Unlock( pbCaptureData, dwCaptureLength, NULL, 0 );
// Перемещение начальной позиции записи
g_dwNextCaptureOffset += dwCaptureLength;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Циклический буфер
if( pbCaptureData2 != NULL )
{
// Запись информации в файл
if( FAILED( hr = g_pWaveSoundWrite->Write( dwCaptureLength2,
(BYTE*)pbCaptureData2,
&dwDataWrote ) ) )
return hr;
// Разблокирование буфера записи
g_pDSBCapture->Unlock( pbCaptureData2, dwCaptureLength2, NULL, 0 );
// Перемещение начальной позиции записи
g_dwNextCaptureOffset += dwCaptureLength2;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Циклический буфер
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Имя: CreateCaptureBuffer()
// Описание: Создаёт буфер записи и устанавливает его формат
//-----------------------------------------------------------------------------
HRESULT Mic_recod::CreateCaptureBuffer()
{
HRESULT hr;
DSCBUFFERDESC dscbd;
if( g_pDSNotify )
g_pDSNotify-> Release();
if( g_pDSBCapture )
g_pDSBCapture-> Release();
// Установка размера извещения
if( g_pwfxInput->nAvgBytesPerSec > 8192 )
g_dwNotifySize = g_pwfxInput->nAvgBytesPerSec >> 3;
else
g_dwNotifySize = 1024;
g_dwNotifySize -= g_dwNotifySize % g_pwfxInput->nBlockAlign;
// Установка размера буфера
g_dwCaptureBufferSize = g_dwNotifySize * NUM_REC_NOTIFICATIONS;
// Создание буфера записи
ZeroMemory( &dscbd, sizeof(dscbd) );
dscbd.dwSize = sizeof(dscbd);
dscbd.dwBufferBytes = g_dwCaptureBufferSize;
dscbd.lpwfxFormat = g_pwfxInput; // Установка формата в процессе создания.
if( FAILED( hr = g_pDSCapture->CreateCaptureBuffer( &dscbd, &g_pDSBCapture, NULL ) ) )
return hr;
g_dwNextCaptureOffset = 0;
if( FAILED( InitNotifications() ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Имя: InitNotifications()
// Описание: Инициализирует процесс посылки извещений, обрабатываемых
// функцией WinMain()
//-----------------------------------------------------------------------------
HRESULT Mic_recod::InitNotifications()
{
HRESULT hr;
if( NULL == g_pDSBCapture )
return E_FAIL;
// Создание объекта события, отмечаемого при остановке записи
if( FAILED( hr = g_pDSBCapture->QueryInterface( IID_IDirectSoundNotify,
(VOID**)&g_pDSNotify ) ) )
return hr;
// Определение позиции отметки события
for( INT i = 0; i < NUM_REC_NOTIFICATIONS; i++ )
{
g_aPosNotify[i].dwOffset = (g_dwNotifySize * i) + g_dwNotifySize - 1;
g_aPosNotify[i].hEventNotify = g_hNotificationEvents[0];
}
g_aPosNotify[i].dwOffset = DSBPN_OFFSETSTOP;
g_aPosNotify[i].hEventNotify = g_hNotificationEvents[1];
// Установка позиций отметки событий. Сообщения об отметке событий обра
// обрабатываются в функции WinMain()
if( FAILED( hr = g_pDSNotify->SetNotificationPositions( NUM_REC_NOTIFICATIONS + 1,
g_aPosNotify ) ) )
return hr;
// Сохранение формата буфера записи в переменной g_pCaptureWaveFormat
if( g_pwfxInput )
delete g_pwfxInput;
g_pwfxInput = new WAVEFORMATEX;
ZeroMemory( g_pwfxInput, sizeof(WAVEFORMATEX) );
g_pDSBCapture->GetFormat( g_pwfxInput, sizeof(WAVEFORMATEX), NULL );
return S_OK;
}
// класс подключаемый к классу Mic_recod для создание структуры wave-файла//
//.h
//-----------------------------------------------------------------------------
// Файл: WavWrite.h
//
// Описание: Файл заголовка класса CWaveSoundWrite
//
//-----------------------------------------------------------------------------
#ifndef WAVE_WRITE_H
#define WAVE_WRITE_H
#include "windows.h"
#include <mmsystem.h>
//-----------------------------------------------------------------------------
// Имя: Класс CWaveSoundWrite
// Описание: Класс, осуществляющий запись аудио информации в файл
//-----------------------------------------------------------------------------
class CWaveSoundWrite
{
public:
HMMIO m_hmmioOut; // Мультимедийный дескриптор файла
MMCKINFO m_ckOut; // Инфоромация о вложенном блоке формата RIFF
MMCKINFO m_ckOutRIFF; // Используется при открытии аудио файла
MMIOINFO m_mmioinfoOut;
CWaveSoundWrite();
~CWaveSoundWrite();
HRESULT Open( LPTSTR, WAVEFORMATEX* );
HRESULT Reset();
HRESULT Write( UINT, BYTE*, UINT* );
HRESULT Close( DWORD );
};
#endif WAVE_WRITE_H
//.cpp
//-----------------------------------------------------------------------------
// Файл: WavWrite.cpp
//
// Описание: Запись аудио информации в файл
//
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "WavWrite.h"
//-----------------------------------------------------------------------------
// Имя: CWaveSoundWrite()
// Описание: Конструктор класса
//-----------------------------------------------------------------------------
CWaveSoundWrite::CWaveSoundWrite()
{
m_hmmioOut = NULL;
}
//-----------------------------------------------------------------------------
// Имя: ~CWaveSoundWrite()
// Описание: Деструктор класса
//-----------------------------------------------------------------------------
CWaveSoundWrite::~CWaveSoundWrite()
{
Close( 0 );
}
//-----------------------------------------------------------------------------
// Имя: Open()
// Описание: Открывает аудио файл для записи
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Open( LPTSTR strFileName, WAVEFORMATEX *pwfxDest )
{
HRESULT hr;
HMMIO hmmioOut = NULL;
if( m_hmmioOut )
Close( 0 );
if( NULL == ( hmmioOut = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF |
MMIO_READWRITE |
MMIO_CREATE ) ) )
return 0;
DWORD dwFactChunk; // Содержимое вложенного блока fact.
// До вызова функции WaveCloseWriteFile содержит
// неопределённую информацию.
dwFactChunk = (DWORD)-1;
// Создание вложенного блока RIFF с идентификатором формата 'WAVE'.
m_ckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
m_ckOutRIFF.cksize = 0;
if( 0 != mmioCreateChunk( hmmioOut, &m_ckOutRIFF, MMIO_CREATERIFF ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}
// Созданный вложенный блок 'RIFF' раскрыт.
// В нём создаётся вложенный блок 'fmt '. Поскольку его размер известен, его
// необходимо указать в объекте структуры MMCKINFO, чтобы MMIO не определял бы
// его при выходе из данного вложенного блока.
m_ckOut.ckid = mmioFOURCC('f', 'm', 't', ' ');
m_ckOut.cksize = sizeof(PCMWAVEFORMAT);
if( 0 != mmioCreateChunk( hmmioOut, &m_ckOut, 0 ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}
// Во вложенный блок 'fmt ' записывается объект структуры PCMWAVEFORMAT.
if( mmioWrite( hmmioOut, (HPSTR) pwfxDest,
sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT))
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}
// Выход из вложенного блока 'fmt ' во вложенный блок 'RIFF'.
if( 0 != mmioAscend( hmmioOut, &m_ckOut, 0 ) )
{
mmioClose( hmmioOut, 0 );
return E_FAIL;
}
m_hmmioOut = hmmioOut;
if( FAILED( hr = Reset() ) )
return hr;
return hr;
}
//-----------------------------------------------------------------------------
// Имя: Reset()
// Описание: Устанавливает текущую позицию записи на начало блока
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Reset()
{
// Создание вложенного блока 'data', в который будет записана аудио информация.
m_ckOut.ckid = mmioFOURCC('d', 'a', 't', 'a');
m_ckOut.cksize = 0;
if( 0 != mmioCreateChunk( m_hmmioOut, &m_ckOut, 0 ) )
return E_FAIL;
if( 0 != mmioGetInfo( m_hmmioOut, &m_mmioinfoOut, 0 ) )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Имя: Write()
// Описание: Сохраняет аудио информацию в файле
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote )
{
UINT cT;
*pnSizeWrote = 0;
for( cT = 0; cT < nSizeToWrite; cT++ )
{
if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite )
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
if( 0 != mmioAdvance( m_hmmioOut, &m_mmioinfoOut, MMIO_WRITE ) )
return E_FAIL;
}
*((BYTE*)m_mmioinfoOut.pchNext) = *((BYTE*)pbData+cT);
(BYTE*)m_mmioinfoOut.pchNext++;
(*pnSizeWrote)++;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Имя: Close()
// Описание: Закрывает аудио файл, открытый для записи.
//-----------------------------------------------------------------------------
HRESULT CWaveSoundWrite::Close( DWORD dwSamples )
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
if( 0 != mmioSetInfo( m_hmmioOut, &m_mmioinfoOut, 0 ) )
return E_FAIL;
// Выход из вложенного блока 'data'. При этом размер записанной информации
// сохраняется в поле размера вложенного блока 'data'.
if( 0 != mmioAscend( m_hmmioOut, &m_ckOut, 0 ) )
return E_FAIL;
// Выход из вложенного блока 'RIFF'. При этом размер записанной информации
// сохраняется в поле размера вложенного блока 'RIFF'.
if( 0 != mmioAscend( m_hmmioOut, &m_ckOutRIFF, 0 ) )
return E_FAIL;
mmioClose( m_hmmioOut, 0 );
return S_OK;
}