2016-06-11 2 views
0

Ich habe mit NAudio mit dem "Fire and Forget Audio-Wiedergabe mit NAudio" Tutorial (danke Mark für diesen tollen Dienstprogramm!), Wie hier geschrieben: http://mark-dot-net.blogspot.nl/2014/02/fire-and-forget-audio-playback-with.htmlNAudio: Mit MixingSampleProvider richtig mit VolumeSampleProvider

ich es geschaffen um einen VolumeSampleProvider hinzuzufügen, der den MixingSampleProvider als Eingabe verwendet. Wenn ich nun aber zwei Sounds hintereinander spiele, bekommt der erste auch immer die Lautstärke der zweiten, obwohl die erste bereits spielt.

Also meine Frage ist: Wie füge ich Sounds mit einer individuellen Lautstärke pro Sound hinzu?

Dies ist, was ich verwendet:

 mixer = new MixingSampleProvider(waveformat); 
     mixer.ReadFully = true; 
     volumeProvider = new VolumeSampleProvider(mixer); 
     panProvider = new PanningSampleProvider(volumeProvider); 
     outputDevice.Init(panProvider); 
     outputDevice.Play(); 

Antwort

1

Ich bin nicht 100% sicher, was Sie fragen, und ich weiß nicht, ob Sie diese bereits gelöst, aber mein nehmen hier ist das auf.

ISampleProvider Objekte spielen das Spiel "Pass the buck" zu ihrer Quelle ISampleProvider über die Read() Methode. Irgendwann macht jemand tatsächlich ein Lesen von Audio-Bytes. Einzelne Klassen ISampleProvider tun, was auch immer sie mit den Bytes tun.

, zum Beispiel, nimmt N Audio-Quellen ... diejenigen gemischt werden. Wenn Read() aufgerufen wird, durchläuft es die Audioquellen und liest count Bytes von jedem.

es zu einem VolumeSampleProvider behandelt alle Bytes (aus diesen verschiedenen Quellen) als Gruppe Passing ... heißt es:

buffer[offset+n] *= volume; 

, dass die Bytes auf der ganzen Linie zu justieren ... geht so jedes Byte wird im Puffer durch den volume Multiplikator eingestellt;

Die PanningSampleProvider bietet nur einen Multiplikator für die Stereo-Audio und passt die Bytes entsprechend, die gleiche Art von tun, wie die VolumeSampleProvider.

Wenn Sie Audioquellen-Volumes einzeln verarbeiten möchten, müssen Sie dies vor dem handhaben. Im Wesentlichen müssen die Dinge, die Sie an den MixingSampleProvider übergeben, in der Lage sein, ihre Lautstärke unabhängig voneinander anpassen zu lassen.

Wenn Sie eine Reihe von SampleChannel Objekte an Ihre MixingSampleProvider übergeben ... können Sie unabhängige Lautstärkeanpassung durchführen. Die Klasse Samplechannel enthält ein VolumeSampleProvider-Objekt und bietet eine Volume-Eigenschaft, die es ermöglicht, die Lautstärke für dieses Objekt festzulegen.

SampleChannel enthält auch eine MeteringSampleProvider, die die Meldung des maximalen Probenwerts während eines bestimmten Zeitraums bereitstellt. Es löst ein Ereignis aus, das Ihnen eine Reihe dieser Werte gibt, einen pro Kanal.

+0

Lieber Matt, danke für diese Antwort. Ich muss mir die SampleChannel-Klasse genauer ansehen, um herauszufinden, ob ich es zum Laufen bringen kann. Es ist über ein Jahr her, seit ich zum letzten Mal an diesem Code gearbeitet habe, daher kann ich mir nicht vorstellen, dass ich es bald wissen werde. Schöne Grüße. – Paul

0

Ich erkannte (dank itsmatt), dass die einzige Möglichkeit, dies zu tun, ist, den Mischer in Ruhe zu lassen und das Panning und das Volumen jedes CachedSound individuell anzupassen, bevor es dem Mixer hinzugefügt wird. Daher musste ich den CachedSoundSampleProvider neu schreiben, indem ich als zusätzliche Eingabeparameter ein Pan und ein Volume verwendete.

Dies ist der neue Konstruktor:

public CachedSoundSampleProvider(CachedSound cachedSound, float volume = 1, float pan = 0) 
    { 
     this.cachedSound = cachedSound; 
     LeftVolume = volume * (0.5f - pan/2); 
     RightVolume = volume * (0.5f + pan/2); 
    } 

Und das ist die neue Read() Funktion:

public int Read(float[] buffer, int offset, int count) 
    { 
     long availableSamples = cachedSound.AudioData.Length - position; 
     long samplesToCopy = Math.Min(availableSamples, count); 

     int destOffset = offset; 
     for (int sourceSample = 0; sourceSample < samplesToCopy; sourceSample += 2) 
     { 
      float outL = cachedSound.AudioData[position + sourceSample + 0]; 
      float outR = cachedSound.AudioData[position + sourceSample + 1]; 

      buffer[destOffset + 0] = outL * LeftVolume; 
      buffer[destOffset + 1] = outR * RightVolume; 
      destOffset += 2; 
     } 

     position += samplesToCopy; 
     return (int)samplesToCopy; 
    }