Микширование аудио с использованием OpenGL - PullRequest
1 голос
/ 15 декабря 2010

Я хочу смешать два (или более) 16-битных аудиопотока, используя OpenGL, и мне нужна небольшая помощь

По сути, я хочу поместить аудио данные в текстуру, которую я рисую в кадреобъект буфера, а затем прочитать обратно.Это не проблема, однако рисование данных таким образом, чтобы получить правильные результаты, немного более проблематично.

У меня есть два основных вопроса.

  1. Чтобы смешать данные с помощьюрисование мне нужно использовать смешивание (альфа = 0,5), однако результат не должен иметь альфа-канал.Так что, если я выполню рендеринг, например, в буфер кадров с форматом RGB, альфа-смешение все еще будет работать, как я ожидаю, и полученная альфа не будет записана в fbo?(Я хочу избежать необходимости читать fbo для каждого прохода рендеринга)

текстура | sR | sG | sB |

framebuffer (перед) | dR | dG| дБ |

кадровый буфер (после) | дР * 0,5 + сР * 0,5 | дГ * 0,5 + сГ * 0,5 | дБ * 0,5 + сБ * 0,5 |

  1. Аудио сэмплы имеют 16-битные целые значения со знаком.Можно ли сделать так подписанные расчеты?Или мне нужно будет сначала преобразовать значения в unsigned на процессоре, нарисовать их, а затем сделать их снова подписанными на процессоре?

РЕДАКТИРОВАТЬ:

Мне было немного неясно,Мое оборудование ограничено оборудованием OpenGL 3.3.Я бы предпочел не использовать CUDA или OpenCL, поскольку я уже использую OpenGL для других вещей.

Каждый аудиосэмпл будет воспроизводиться в отдельных проходах, что означает, что он должен «смешиваться» с тем, что уже былоотображается в буфер кадра.Проблема заключается в том, как вывод пиксельного шейдера записывается в кадровый буфер (насколько я знаю, это смешивание недоступно через программируемые шейдеры, и нужно использовать glBlendFunc).

EDIT2:

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

foreach(var audio_sample in audio_samples)
     draw(audio_sample);

и не

for(int n = 0; n < audio_samples.size(); ++n)
{
      glActiveTexture(GL_TEXTURE0 + n);
      glBindTexture(audio_sample);
}
draw_everything();

Ответы [ 3 ]

4 голосов
/ 15 декабря 2010

Честно говоря, почему бы вам не использовать для этого программируемые пиксельные шейдеры?

Нужно ли использовать OpenGL 1 Fixed Functionality Pipeline?

Я бы просто пошел с программируемым шейдером, работающим на 16-битных линейных текстурах в оттенках серого.

Edit:

foreach(var audio_sample in audio_samples) 
 blend FBO1 + audio_sample => FBO2
 swap FBO2, FBO1 

Это должно быть так же быстро, если не быстрее (благодаря потоковым конвейерам).

2 голосов
/ 15 декабря 2010

Я согласен с QDot.Не могли бы вы, однако, сообщить нам немного об аппаратных ограничениях, с которыми вы сталкиваетесь?Если у вас есть разумное современное оборудование, я мог бы даже предложить пойти по пути CUDA или OpenCL вместо того, чтобы проходить через OpenGL.

1 голос
/ 15 декабря 2010
  1. Вы сможете смешивать, даже если в буфере назначения нет альфа. Тем не менее, рендеринг до размеров, отличных от двух (rgb16 = 6 байт / пиксель), обычно приводит к снижению производительности.

  2. Signed не является вашим типичным целевым форматом рендеринга, но он существует в спецификации OpenGL 4.0 (Таблица 3.12, которая называется RGB16_SNORM или RGB16I, в зависимости от того, хотите ли вы нормализованное представление или нет).

В качестве примечания у вас также есть glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA), чтобы вам даже не приходилось указывать альфа на пиксель. Это может быть доступно не во всех реализациях GL.

...