Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TAPI и WaveIn/WaveOut. 
:(
    Опции темы
AndreySol
Дата 14.6.2007, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



На форумах несколько раз попадалось, что люди успешно делали прослушивание линии / проигрывание в линию.
Мне необходимо сделать прослушивание линии, причем желательно с момента начала набора номера (если такое возможно).
Просветите, как такое сделать ?
PM MAIL   Вверх
Romikgy
Дата 22.6.2007, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7325
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



имхо теоретически можно , но подключаемый модем паралельно к линии будет ее садить сильно , и будет слышно что тя пишут :(


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
AndreySol
Дата 28.6.2007, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



Нет параллельное подключение не нуно, нуно через сам модем прослушивать.
В принципе я разобрался как сделать прием данных с линии используя WaveIn...-функции, однако не получается затем принятые данные синхронно скармливать WaveOut..-функциям - начинается бардак, судя по всему из-за отсутствия синхронизации приема\передачи.

PM MAIL   Вверх
black_priest
Дата 28.6.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 19.3.2007
Где: Minsk

Репутация: нет
Всего: нет



Я так понимаю ты "скармливаешь" данные WaveOut для того чтобы их услышать? И если можно в двух словах как ты данные с линии получаешь, тема заинтересовала, сам со звуком вожусь. Если есть данные, то WaveOut должна их проигрывать, есть только пара тонких моментов на которых сперва можно сподкнуться.

Это сообщение отредактировал(а) black_priest - 28.6.2007, 18:44
PM MAIL   Вверх
AndreySol
Дата 29.6.2007, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



Сначала обычным способом открываю линию, получаю ID-ы для "wave/in" и "wave/out".
Затем при соединении запускаю получение данных с линии в WaveIn...-функции:
Код

static int g_WaveInSize = 0;
static char g_WaveInBuffer1[2*8000];
static char g_WaveOutBuffer1[2*8000];

// ф-ция обратного вызова для WaveIn
static void CALLBACK WaveInCallback(HWAVEIN hWaveIn, UINT wMsg, DWORD dwUser, WAVEHDR* pWaveHeader, DWORD dw2)
{
    if(wMsg == WIM_DATA)
    {
        MMRESULT Error = MMSYSERR_NOERROR;
        CMyDlg* pDlg = reinterpret_cast<CMyDlg*>(dwUser);

        // общее кол-во полученных с линии данных
        g_WaveInSize += pWaveHeader->dwBytesRecorded;

        // копируем данные в буфер WaveOut...
        memcpy(g_WaveOutBuffer1, pWaveHeader->lpData, pWaveHeader->dwBytesRecorded);

        if(pDlg -> bIsProcedingWaveOut != TRUE)
        {    // запускаем прослушивание линии (WaveOut)
            pDlg -> ProcedingWaveOut();
        }

        // пишем данные в файл
        pDlg->WriteData(pWaveHeader);

        // продолжаем получение данных с линии
        if(waveInUnprepareHeader(hWaveIn, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
        {
            if(waveInPrepareHeader(hWaveIn, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
            {
                if(waveInAddBuffer(hWaveIn, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
                {

                }
            }
        }
    }
}

BOOL CMyDlg::ProcedingWaveIn()
{
    if(bIsProcedingWaveIn == TRUE)
        return TRUE;

    // подготавливаем waveIn
    if((mmResult = waveInOpen(&hWaveIn, WaveInID, &WaveFormat, (DWORD)WaveInCallback, (DWORD)this, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
    {
        GetErrorWave(mmResult, TRUE);

        return FALSE;
    }

    pWaveInHeader1 = new WAVEHDR;
    memset(pWaveInHeader1, 0, sizeof(WAVEHDR));
    pWaveInHeader1->lpData = g_WaveInBuffer1;
    pWaveInHeader1->dwBufferLength = sizeof(g_WaveInBuffer1);
    pWaveInHeader1->dwUser = NULL;
    pWaveInHeader1->dwFlags = 0;
    pWaveInHeader1->dwLoops = 0;

    if((mmResult = waveInPrepareHeader(hWaveIn, pWaveInHeader1, sizeof(WAVEHDR))) != MMSYSERR_NOERROR)
    {
        GetErrorWave(mmResult, TRUE);

        waveInClose(hWaveIn);
        return FALSE;
    }

    if((mmResult = waveInAddBuffer(hWaveIn, pWaveInHeader1, sizeof(WAVEHDR))) != MMSYSERR_NOERROR)
    {
        GetErrorWave(mmResult, TRUE);

        waveInUnprepareHeader(hWaveIn, pWaveInHeader1, sizeof(WAVEHDR));
        waveInClose(hWaveIn);
        return FALSE;
    }

    if((mmResult = waveInStart(hWaveIn)) != MMSYSERR_NOERROR)
    {
        bIsProcedingWaveIn = FALSE;

        GetErrorWave(mmResult, TRUE);

        waveInUnprepareHeader(hWaveIn, pWaveInHeader1, sizeof(WAVEHDR));
        waveInClose(hWaveIn);
        return FALSE;
    }
    else
    {    // флаг начала записи данных с линии
        bIsProcedingWaveIn = TRUE;    
        
        // подготовливаем файл для записи в него данных
        szFileWriteName = "d:\\test.wav";

        if(fileWrite.Open(szFileWriteName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary))
        {
            bIsOpenFileWrite = TRUE;

        }
        else
        {
            bIsOpenFileWrite = FALSE;

            return FALSE;
        }
    }

    return TRUE;
}

затем пытаюсь полученные в WaveIn данные передать в WaveOut:
Код

// ф-ция обратного вызова для WaveOut
static void CALLBACK WaveOutCallback(HWAVEOUT hWaveOut, UINT wMsg, DWORD dwUser, WAVEHDR* pWaveHeader, DWORD dw2)
{
    if(wMsg == WOM_DONE)
    {
        // подготавливаем
        if(waveOutUnprepareHeader(hWaveOut, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
        {
            if(waveOutPrepareHeader(hWaveOut, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
            {    // воспроизводим
                if(waveOutWrite(hWaveOut, pWaveHeader, sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
                {

                }
            }
        }
    }
}

BOOL CMyDlg::ProcedingWaveOut()
{
    if(bIsProcedingWaveOut == TRUE)
        return TRUE;

    // подготавливаем waveOut
    if((mmResult = waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFormat, (DWORD)WaveOutCallback, (DWORD)this, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR )
    {
        GetErrorWave(mmResult, FALSE);

        return FALSE;
    }

    pWaveOutHeader1 = new WAVEHDR;
    memset(pWaveOutHeader1, 0, sizeof(WAVEHDR));
    pWaveOutHeader1->lpData = g_WaveOutBuffer1;
    pWaveOutHeader1->dwBufferLength = sizeof(g_WaveOutBuffer1);
    pWaveOutHeader1->dwUser = NULL;
    pWaveOutHeader1->dwFlags = 0;
    pWaveOutHeader1->dwLoops = 0;

    if((mmResult = waveOutPrepareHeader(hWaveOut, pWaveOutHeader1, sizeof(WAVEHDR))) != MMSYSERR_NOERROR )
    {
        GetErrorWave(mmResult, FALSE);

        waveOutClose(hWaveOut);
        return FALSE;
    }

    if((mmResult = waveOutWrite(hWaveOut, pWaveOutHeader1, sizeof(WAVEHDR))) != MMSYSERR_NOERROR )
    {
        GetErrorWave(mmResult, FALSE);

        waveOutUnprepareHeader(hWaveOut, pWaveOutHeader1, sizeof(WAVEHDR));
        waveOutClose(hWaveOut);
        return FALSE;
    }

    // флаг начала воспроизведения
    bIsProcedingWaveOut = TRUE;
    
    return TRUE;
}

Т.е. в общем получается, что как только получена первая порция данных, в WaveInCallback копируем эти данные в буфер для WaveOut и запускаем воспроизведение.
Результат следующий - в контрольный файл входные данные пишутся прекрасно, а на прослушивании идут накладки и пропуски звука.
Какие есть идеи как синхронизировать WaveOut относительно WaveIn ?
PM MAIL   Вверх
black_priest
Дата 29.6.2007, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 19.3.2007
Где: Minsk

Репутация: нет
Всего: нет



Вообще, в таких случаях нужно использовать принцип двойной буферизации. Т. е. при проигрывании очередного буфера функцией waveOut, следующий буфер на проигрывание уже должен быть в очереди, тогда поток воспроизведения будет непрерывным. И с получением звука тоже нужно так поступать. Насколько я помню, если не использовать это, то в момент переключения  буферов будут раздоваться щелчки.
PM MAIL   Вверх
AndreySol
Дата 7.7.2007, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



Да пробовал я эту двойную буферизацию, проблемы синхронизации WaveOut относительно WaveIn она не решает.
Может еще какие мысли ?
PM MAIL   Вверх
Romikgy
Дата 7.7.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7325
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(AndreySol @  7.7.2007,  10:32 Найти цитируемый пост)
Может еще какие мысли ? 

можно попробывать в цикле , читать и писать маленькими кусочками, только обезопасится от зависаний при чтении и отсутствие данных, типа таймаутов у ком порта 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
AndreySol
Дата 8.7.2007, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



Примерчик бы, а то ничего дельного в голову не приходит.

Кстати, проблему вобщем-то решить можно через DirectShow - после установки Voice-модема (по крайней мере у меня) появляется два фильтра, которые могут принимать и передавать данные по нему, естественно без всяких проблем. Причем используя стандартный фильтр-расщепитель сигнала (InfTee кажись) мона сигнал подать на прослушку и на запись.

Вот только знать-бы, что такие фильтры есть обязательное дело для всех Voice-модемов ?
PM MAIL   Вверх
Romikgy
Дата 8.7.2007, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7325
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



имхо 
Цитата(AndreySol @  8.7.2007,  11:09 Найти цитируемый пост)
фильтр-расщепитель

часть 
Цитата(AndreySol @  8.7.2007,  11:09 Найти цитируемый пост)
DirectShow

и применяется к модемам , у которых есть 
Цитата(AndreySol @  8.7.2007,  11:09 Найти цитируемый пост)
 Voice

режим, и этот фильтр притсуствует в системе в не зависимости есть ли в системе модем вообще
имхо


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
black_priest
Дата 8.7.2007, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 19.3.2007
Где: Minsk

Репутация: нет
Всего: нет



Не знаю, у меня решает. Просто может где-то ошибаешься. Оцифровывать звук и  одновременно воспроизводить его с некоторой задержкой - вполне решаемая задача с помощью waveIn/Out функций.
PM MAIL   Вверх
AndreySol
Дата 9.7.2007, 07:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



black_priest 
Блин, дайте код - хотябы тот момент где реализована прослушка линии !
 smile 
PM MAIL   Вверх
AndreySol
Дата 14.7.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 772
Регистрация: 19.6.2004

Репутация: нет
Всего: 1



black_priest
отзовитесь пожалуйста !
PM MAIL   Вверх
black_priest
Дата 6.8.2007, 08:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 19.3.2007
Где: Minsk

Репутация: нет
Всего: нет



Я прошу прощения за паузу, но честно говоря с кодом, который прослушивает линию не могу помочь. К сожалению, я не работал с TAPI, я работал с waveIn/Out функциями и наталкивался на проблемы синхронизации о которых ты пишешь. Не совсем понимаю, что значит
Цитата
Сначала обычным способом открываю линию, получаю ID-ы для "wave/in" и "wave/out"

или под прослушкой линии имеется ввиду что-то другое?
PM MAIL   Вверх
Ciminance
Дата 24.10.2022, 06:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 24.10.2022

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1514 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.