2010-12-15 12 views
1

Ich mag zwei mischen (oder mehr) 16-Bit-Audio-Streams mit Hilfe von OpenGL und ich brauche ein wenig HilfeMischen von Audio OpenGL

Im Grunde, was ich tun möchte, ist die Audiodaten in Textur zu setzen, die mich zu zeichnen ein Rahmenpufferobjekt und dann zurückgelesen. Dies ist kein Problem, jedoch ist das Zeichnen der Daten, die korrekte Ergebnisse liefern, etwas problematischer.

Ich habe im Grunde zwei Fragen.

  1. Um die Daten durch Zeichnen zu mischen, brauche ich eine Mischung (Alpha = 0,5), aber das Ergebnis sollte keinen Alphakanal haben. Wenn ich also z. ein Frame-Buffer mit dem Format RGB wird Alpha-Blending immer noch funktionieren, wie ich es erwarte und das resultierende Alpha wird nicht in die Fbo geschrieben? (Ich will, um zu vermeiden, die fbo zu lesen wieder für jeden Durchgang machen)

Textur | sR | sG | sB |

Framebuffer (vorher) | dR | dG | dB |

Framebuffer (nach) | dR * 0,5 + sR * 0,5 | dG * 0,5 + sG * 0,5 | dB * 0,5 + sB * 0,5 |

  1. Die Audioabtastwerte sind 16-Bit-Integer-Werte signiert. Ist es möglich, signierte Berechnungen auf diese Weise zu machen? Oder muss ich zuerst die Werte in die CPU ohne Vorzeichen konvertieren, sie zeichnen und sie dann wieder signiert auf der CPU machen?

EDIT:

Ich war ein wenig unklar. Meine Hardware ist auf OpenGL 3.3 Hardware beschränkt. Ich würde lieber nicht CUDA oder OpenCL verwenden, da ich OpenGL für andere Sachen benutze.

Jedes Audio-Sample wird in separaten Pässen gerendert, was bedeutet, dass es sich mit dem "mischen" muss, was bereits in den Framebuffer gerendert wurde. Das Problem ist, wie die Ausgabe vom Pixelshader in den Framebuffer geschrieben wird (diese Mischung ist, soweit ich weiß, nicht über programmierbare Shader zugänglich, und man muss glBlendFunc verwenden).

EDIT2:

Jede Hörprobe wird in verschiedenen Durchgängen wiedergegeben werden, so dass nur ein Audio-Abtastwert wird im Shader zu einem Zeitpunkt zur Verfügung steht, was bedeutet, dass sie in der FBO akkumuliert werden müssen.

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

und nicht

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

Antwort

1
  1. Sie sollten auch dann mischen können, wenn der Zielpuffer kein Alpha hat. Das heißt, das Rendern auf Nicht-Zweierpotenz-Größen (rgb16 = 6 Bytes/Pixel) verursacht normalerweise Leistungseinbußen.

  2. Signed ist nicht Ihr typisches Renderzielformat, aber es existiert in der OpenGL 4.0-Spezifikation (Tabelle 3.12, RGB16_SNORM oder RGB16I genannt, je nachdem, ob Sie eine normalisierte Darstellung wünschen oder nicht).

Als Randbemerkung, haben Sie auch glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA) nicht einmal einen Alpha-pro-Pixel angeben haben. Dies ist jedoch möglicherweise nicht für alle GL-Implementierungen verfügbar.

4

Ehrlich gesagt, warum würden Sie nicht verwenden nur programmierbare Pixel-Shader für das?

Müssen Sie OpenGL 1 Fixed Functionality Pipeline verwenden?

Ich würde nur mit einem programmierbaren Shader gehen, der auf vorzeichenbehafteten 16bit Graustufen linearen Texturen arbeitet.

Edit:

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

Es sollte nur so schnell, wenn nicht schneller (dank Streaming-Pipelines) sein.

+0

Ein Pixel-Shader wäre wahrscheinlich nützlich. Das Problem ist jedoch, wie ich das Ergebnis vom Pixelshader korrekt in den Framebuffer geschrieben habe, da es sich mit dem mischen sollte, was bereits im Framebuffer ist. Vielleicht war ich ein bisschen unklar. Aber jedes "Audio Sample" wird in separaten Pässen gerendert. Sooo, ich werde nur im Shader darauf zugreifen können. – ronag

+2

Sie können einen Pixel-Shader in ein PBO oder FBO rendern lassen, ohne sich um den Alphakanal des PBO kümmern zu müssen (Sie können sie einfach deaktivieren und zwei Texturen direkt mit einem Shader mischen). – qdot

+0

Ja, aber ich habe keinen Zugriff mehr als eine Textur im Shader, da jedes Audio-Sample in verschiedenen Durchläufen gerendert wird. Sie müssen Pass-by-Pass im FBO angesammelt werden. – ronag

2

Ich stimme mit QDot überein. Könnten Sie uns jedoch etwas über die Hardware-Einschränkungen informieren, denen Sie gegenüberstehen? Wenn Sie über eine vernünftige moderne Hardware verfügen, könnte ich sogar vorschlagen, die CUDA- oder OpenCL-Route zu wählen, statt OpenGL zu verwenden.

+0

Bearbeitete meinen Beitrag. – ronag

+0

Gibt es einen wirklich überzeugenden Grund, über OpenGL zu gehen? Müssen Sie etwas mit etwas verbinden? – Bart

+0

Nun, der Hauptgrund ist, dass ich keine weitere Abhängigkeit hinzufügen möchte, wenn es nicht notwendig ist ... es scheint nicht gerechtfertigt, OpenCL nur dafür einzubeziehen ... besonders, wenn ich den Job mit OpenGL machen kann, das alrdy verwendet wird ausgiebig in meinem Projekt. – ronag