вопрос по waveaudio
От: dennisV Россия http://dennis.psunrise.com
Дата: 16.02.02 08:43
Оценка:
Помогите, пожалуйста!
Есть ли реальная возможность (впрочем нереальная тоже подойдет) проиграть waveaudio, используя обычные mciSendString (или command), но не с диска, а из буффера в памяти? Проблема такая — есть звуковой файл, он зашифрован. Требуется — загрузить его в память, расшифровать (тут у меня проблем нет), а затем эту кучу битов запихнуть в звуковую карточку. Я могу идти и по ложному следу, поэтому с радостью приму любую информацию по этому вопросу. Спасибо.

Денис
MCP, MCSD
Re: вопрос по waveaudio
От: Lostar Россия  
Дата: 17.02.02 09:56
Оценка: 2 (1)
Здравствуйте dennisV, Вы писали:

V>Помогите, пожалуйста!

V>Есть ли реальная возможность (впрочем нереальная тоже подойдет) проиграть waveaudio, используя обычные mciSendString (или command), но не с диска, а из буффера в памяти?
может и можно ... :о) точно не знаю. Я бы поюзал DirectSound. Если звуковой файл не очень длинный то можно даже без использования stream
например:
#define INITGUID
#include <dsound.h>
#include <iostream>
#include <time.h>
#include <ks.h> // GUID_NULL

LPDIRECTSOUND8    pDSound = NULL;
LPDIRECTSOUNDBUFFER    pDSPrimaryBuffer = NULL;
LPDIRECTSOUNDBUFFER    pDSSecondaryBuffer = NULL;

int Exit()
{
    getchar();
    if (pDSPrimaryBuffer) { pDSPrimaryBuffer->Release(); pDSPrimaryBuffer = NULL; }
    if (pDSSecondaryBuffer) { pDSSecondaryBuffer->Release(); pDSSecondaryBuffer = NULL; }
    if (pDSound) { pDSound->Release(); pDSound = NULL; }

    CoUninitialize();
    
    return 0;
}
int main(int argc, char* argv[])
{
    HRESULT    hResult;

    if (FAILED(CoInitialize(NULL))) { std::cout << "CoInitialize FAIL\n"; return Exit(); }

    // create Direct Sound device
    DirectSoundCreate8(NULL, &pDSound, NULL);
    if (!pDSound) { std::cout << "Direct Sound object not created\n"; return Exit(); }
    else std::cout << "Direct Sound object created\n";

    // check compatibles
    DSCAPS    m_DScaps;
    memset(&m_DScaps, 0, sizeof(m_DScaps));
    m_DScaps.dwSize = sizeof(m_DScaps);
    hResult = pDSound->GetCaps(&m_DScaps);
    if (FAILED(hResult)) { std::cout << "Error in GetCaps, error code:" << hResult << "\n"; return Exit(); }
    else std::cout << "GetCaps OK\n";

    if (m_DScaps.dwFlags & DSCAPS_EMULDRIVER) std::cout << "  Direct Sound driver not present. Use software emulation.\n";
    else std::cout << "  Direct Sound driver present.\n";
    if (m_DScaps.dwFlags & DSCAPS_PRIMARYSTEREO) std::cout << "   Primary stereo mode avalible.\n";
    if (m_DScaps.dwFlags & DSCAPS_SECONDARYSTEREO) std::cout << "   Hardware mixed stereo mode avalible.\n";

    // set cooperative level
    hResult = pDSound->SetCooperativeLevel(GetForegroundWindow(), DSSCL_PRIORITY);
    if (FAILED(hResult)) { std::cout << "Error in SetCooperativeLevel, error code:" << hResult << "\n"; return Exit(); }
    else std::cout << "SetCooperativeLevel - DSSCL_PRIORITY\n";

    // create secondary sound buffer
    DSBUFFERDESC    m_DSBufferDesc;
    WAVEFORMATEX    m_waveFormatEx;
    m_waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
    m_waveFormatEx.cbSize = 0; // ignore for WAVE_FORMAT_PCM
    m_waveFormatEx.nChannels = 2; // stereo (1 - mono)
    m_waveFormatEx.nSamplesPerSec = 44100; // 44.1 kHz
    m_waveFormatEx.wBitsPerSample = 16; // 16 bit (or 8)
    m_waveFormatEx.nBlockAlign = m_waveFormatEx.wBitsPerSample / 8 * m_waveFormatEx.nChannels;
    m_waveFormatEx.nAvgBytesPerSec = m_waveFormatEx.nSamplesPerSec * m_waveFormatEx.nBlockAlign;

    memset(&m_DSBufferDesc, 0, sizeof(m_DSBufferDesc));
    m_DSBufferDesc.dwSize = sizeof(m_DSBufferDesc);
    m_DSBufferDesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS;
        // задаем размер буфера под звук
    m_DSBufferDesc.dwBufferBytes = 44100/*Hz*/ * 10/*sec*/ * 2/*16 bit per sample*/ * 2/*2 chanel*/;
    m_DSBufferDesc.guid3DAlgorithm = DS3DALG_DEFAULT;
    m_DSBufferDesc.lpwfxFormat = &m_waveFormatEx;
    
    hResult = pDSound->CreateSoundBuffer(&m_DSBufferDesc, &pDSSecondaryBuffer, NULL);
    if (FAILED(hResult)) { std::cout << "Error in CreateSoundBuffer(secondary), error code:" << hResult << "\n"; return Exit(); }
    else std::cout << "CreateSoundBuffer(secondary) OK\n";

    // fill secondary buffer
    void *buffer1 = NULL;
    DWORD dwBufferSize1 = 0;

    hResult = pDSSecondaryBuffer->Lock(0, 0, &buffer1, &dwBufferSize1, NULL, 0, DSBLOCK_ENTIREBUFFER);
    if (FAILED(hResult)) { std::cout << "Error in Lock(secondary), error code:" << hResult << "\n"; return Exit(); }

        // копируем данные из твоего буфера в буфер DirectSound
        memcpy(buffer1, pointerYourBUFFER, dwBufferSize1);

    hResult = pDSSecondaryBuffer->Unlock(buffer1, dwBufferSize1, NULL, 0);
    if (FAILED(hResult)) { std::cout << "Error in Unlock(secondary), error code:" << hResult << "\n"; return Exit(); }

    pDSSecondaryBuffer->SetCurrentPosition(0);

    // play secondary buffer
    hResult = pDSSecondaryBuffer->Play(0, 0, 0/*DSBPLAY_LOOPING*/);
    if (FAILED(hResult)) { std::cout << "Error in Play(secondary), error code:" << hResult << "\n"; return Exit(); }
    else std::cout << "Play(secondary) OK\n";

    getchar();
    
    // stop secondary
    hResult = pDSSecondaryBuffer->Stop();
    if (FAILED(hResult)) { std::cout << "Error in Stop(secondary), error code:" << hResult << "\n"; return Exit(); }
    else std::cout << "Stop(secondary) OK\n";

    return Exit();
}
С уважением, Николай.
Re[2]: вопрос по waveaudio
От: dennisV Россия http://dennis.psunrise.com
Дата: 17.02.02 17:27
Оценка:
Здравствуйте Lostar, Вы писали:

L>может и можно ... :о) точно не знаю. Я бы поюзал DirectSound. Если звуковой файл не очень длинный то можно даже без использования stream


Спасибо за рекомендацию, но я хотел бы обойтись без DirectX'а, т.к. не знаю, будет ли он у пользователей, а redist не люблю таскать с прогами, а также мне было бы более интересно посмотреть можно ли каким-либо образом спуститься на более низкий уровень и работать с битами, но при этом используя HAL виндов. В любом случае — спасибо.
MCP, MCSD
Re: вопрос по waveaudio
От: ua1zcl Россия www.alexklm.ru
Дата: 17.02.02 22:06
Оценка: 2 (1)
Здравствуйте dennisV, Вы писали:

V>Помогите, пожалуйста!

V>Есть ли реальная возможность (впрочем нереальная тоже подойдет) проиграть waveaudio, используя обычные mciSendString (или command), но не с диска, а из буффера в памяти? Проблема такая — есть звуковой файл, он зашифрован. Требуется — загрузить его в память, расшифровать (тут у меня проблем нет), а затем эту кучу битов запихнуть в звуковую карточку. :???: Я могу идти и по ложному следу, поэтому с радостью приму любую информацию по этому вопросу. Спасибо.

V> Денис

Я делал так:

sndPlaySound((LPCSTR)hMemBtnClk,SND_MEMORY|SND_SYNC);

Более полный код:

DWORD WINAPI StartAddress(PVOID pv);
static bool bThrdBusy;

bool MakeSoundThread(void)
{ DWORD dwThrId;
HANDLE hThread;
if(bThrdBusy)return 0;
if(!hMemBtnClk)return 0;
hThread=CreateThread(0,1000,(LPTHREAD_START_ROUTINE)StartAddress,0,0,&dwThrId);
SetThreadPriority(hThread,THREAD_PRIORITY_TIME_CRITICAL);
return 1;
}

static bool bPlaying;

DWORD WINAPI StartAddress(PVOID pv)
{

waveOutGetVolume((PVOID)-1,&dwPrevWaveVolume);
waveOutSetVolume((PVOID)-1,MAKELONG(uBntClkVolume*640,uBntClkVolume*640));
sndPlaySound((LPCSTR)hMemBtnClk,SND_MEMORY|SND_SYNC);bPlaying=1;
waveOutSetVolume((PVOID)-1,dwPrevWaveVolume);
bThrdBusy=bPlaying=0;
ExitThread(0);
return (DWORD)pv;
}
/////////////////////////////////////////////////////////////////////////////
:super:
Александр
Re[2]: вопрос по waveaudio
От: dennisV Россия http://dennis.psunrise.com
Дата: 18.02.02 13:23
Оценка:
Здравствуйте ua1zcl, Вы писали:

U>Я делал так:


U>sndPlaySound((LPCSTR)hMemBtnClk,SND_MEMORY|SND_SYNC);


Спасибо за подсказку... Попробую поэкспериментировать с PlaySound(), т.к. в MSDN говорится, что sndPlaySound() сохранена только для совместимости... Вроде говорят, надо теперь использовать PlaySound().

Денис
MCP, MCSD
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.