2015-01-09 2 views
0

У меня нет опыта в аудиопрограмме, а C++ - это язык с низким уровнем, поэтому у меня есть небольшие проблемы с ним. Я работаю с ASIO SDK 2.3, загруженным с http://www.steinberg.net/en/company/developers.html.C++ ASIO, доступ к буферам

Я пишу свой собственный хост на основе примера внутри SDK.

На данный момент мне удалось пройти весь образец, и похоже, что он работает. У меня есть внешняя звуковая карта, подключенная к компьютеру. Я успешно загрузил драйвер для этого устройства, настроил его, обработал обратные вызовы, литые данные с аналогового на цифровой и т. Д.

И часть, где я застрял сейчас: Когда я воспроизвожу какую-то дорожку через свое устройство, я вижу полосы, перемещающиеся в микшере (программное обеспечение устройства). Таким образом, устройство подключено правильно. В моем коде я выбрал входы и выходы с именами баров, которые перемещаются в микшере. Я также использовал ASIOCreateBuffers() для создания буфера для каждого ввода/вывода.

  1. Теперь исправьте меня, если я ошибаюсь: Когда ASIOStart() вызывается и водитель находится в рабочем состоянии, когда входной звуковой сигнал для моего внешнего устройства я считаю, что буферы заполняются данными, не так ли?

  2. Я читаю документацию, но я немного потерял - как я могу получить доступ к данным, отправляемым устройством в приложение, хранящимся в буферах INPUT? Или сигнал? Мне нужно это для анализа сигналов или, возможно, записи в будущем.

EDIT: Если бы я сделал это сложным, то в двух словах мой вопрос: как я могу получить доступ к данным потока ввода из кода? Я не вижу никаких объектов/обратных вызовов, позволяющих мне делать это в документации.

+2

Я считаю, что тег 'boost-asio' не применим к этому вопросу, вы спрашиваете об SDK, связанном с аудио, а не о асинхронном модуле io. –

+0

Вы правы, я отредактировал его, спасибо. – F1sher

ответ

0

Хозяин в ASIO SDK довольно близок к тому, что вам нужно. В bufferSwitchTimeInfo обратного вызова есть некоторый код следующим образом:

for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++) 
{ 
    int ch = asioDriverInfo.bufferInfos[i].channelNum; 
    if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue) 
    { 
     char* buf = asioDriver.bufferInfos[i].buffers[index]; 
     .... 

Внутри что если блок asioDriver.bufferInfos[i].buffers[index] является указателем на исходную аудиоданные (index является параметром метода).

Формат буфера зависит от водителя и может быть обнаружен путем тестирования asioDriverInfo.channelInfos[i].type. Типы форматов будут состоять из 32 бит int LSB, сначала 32 бит int MSB и так далее. Список значений можно найти в списке ASIOSampleType в asio.h. На этом этапе вы захотите преобразовать образцы в некоторый общий формат для кода обработки сигнала ниже по потоку. Если вы выполняете обработку сигнала, вы, вероятно, захотите преобразовать его в double. Файл host\asioconvertsample.cpp даст вам некоторое представление о том, что связано с преобразованием. Наиболее распространенным форматом, который вы собираетесь встретить, вероятно, является INT32 MSB. Вот как вы конвертируете его в двойное.

for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++) 
{ 
    int ch = asioDriverInfo.bufferInfos[i].channelNum; 
    if (asioDriverInfo.bufferInfos[i].isInput == ASIOTrue) 
    { 
     switch (asioDriverInfo.channelInfos[i].type) 
     { 
      case ASIOInt32LSB: 
      { 
       double* pDoubleBuf = new double[_bufferSize]; 
       for (int i = 0 ; i < _bufferSize ; ++i) 
       { 
        pDoubleBuf[i] = *(int*)asioDriverInfo.bufferInfos.buffers[index]/(double)0x7fffffff; 
       } 
       // now pDoubleBuf contains one channels worth of samples in the range of -1.0 to 1.0. 
       break; 
      } 
      // and so on... 
+0

Спасибо человек. Это действительно сработало. Хотя я играю музыку на своем устройстве, а в программе я получаю только 0.0, но все же я получил доступ к блоку памяти и получил значение. – F1sher

+0

Хорошо, это работает :) Еще раз спасибо! – F1sher

+0

На самом деле: D нравится: * ((int *) asioDriverInfo.bufferInfos.buffers [index] + i) и double * pDoubleBuf = новый double [_bufferSize]; не должен быть в обратном вызове или в цикле, потому что это утечка памяти – F1sher

0

спасибо. Ваш ответ очень помог, но поскольку я немного неопытен с C++: P Я считаю это немного проблематичным.

В общем, я написал свой собственный хост на основе hostsample. Я не реализовал структуру asioDriverInfo и теперь использую общие переменные.

  1. Моя первая проблема была :.

    char* buf = asioDriver.bufferInfos[i].buffers[index]; 
    

    как я получил сообщение об ошибке, что я не могу бросить (Недействительными *), чтобы символ *, но это, вероятно, решить эту проблему:

    char* buf = static_cast<char*>(bufferInfos[i].buffers[doubleBufferIndex]); 
    
  2. Моя вторая проблема с преобразованием данных. Я проверил файл, который вы мне рекомендовали, но я нахожу его маленькой черной магией. Сейчас я пытаюсь последовать вашему примеру и:

    for (int i = 0; i < inputBuffers + outputBuffers; i++) 
    { 
        if (bufferInfos[i].isInput) 
        { 
         switch (channelInfos[i].type) 
         { 
          case ASIOSTInt32LSB: 
          { 
           double* pDoubleBuf = new double[buffSize]; 
           for (int j = 0 ; j < buffSize ; ++j) 
           { 
            pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex]/(double)0x7fffffff; 
           } 
           break; 
          } 
         } 
        } 
    

    Я получаю ошибку там:

    pDoubleBuf[j] = bufferInfos[i].buffers[doubleBufferIndex]/(double)0x7fffffff; 
    

    , который:

    error C2296: '/' : illegal, left operand has type 'void *' 
    

То, что я не получаю что в вашем примере нет таблицы: asioDriverInfo.bufferInfos.buffers [index] после bufferInfos и даже если я его исправлю ... к какому типу я должен использовать его t o заставить его работать. P

PS. Я уверен, что тип данных ASIOSTInt32LSB подходит для моего ПК.

+0

Я только что обновил свой ответ, чтобы справиться с ошибкой. Вам нужно отбрасывать из void * в любой тип данных, который вам нужен. для 32-битных типов, которые были бы только для int. Для 24-битных типов вам нужно будет сбрасывать байт, а затем переводить его в int и т. Д. – jaket

Смежные вопросы