[vlc-commits] commit: iOS: audio output module (Based on the AudioQueue API) ( Romain Goyet )

git at videolan.org git at videolan.org
Thu Sep 16 01:12:46 CEST 2010


vlc | branch: master | Romain Goyet <romain.goyet at likid.org> | Sat Sep 11 19:17:54 2010 +0200| [aa9ba2d5df9b2885d9deecb81c7434cb9c1f2417] | committer: Jean-Baptiste Kempf 

iOS: audio output module (Based on the AudioQueue API)

This audio output is still quite young, but works fine on existing iOS devices.
In theory this can also be used on Mac OS X as well, but for now it's not as powerful as the existing CoreAudio driver.

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=aa9ba2d5df9b2885d9deecb81c7434cb9c1f2417
---

 configure.ac                      |   11 +++
 modules/audio_output/Modules.am   |    1 +
 modules/audio_output/audioqueue.c |  175 +++++++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9f40507..3b83d7c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3589,6 +3589,17 @@ then
 fi
 
 dnl
+dnl  AudioQueue plugin
+dnl
+AC_ARG_ENABLE(audioqueue,
+  [  --enable-audioqueue       AudioQueue audio module (default disabled)])
+if test "${enable_audioqueue}" = "yes"
+then
+  VLC_ADD_PLUGIN([audioqueue])
+  VLC_ADD_LDFLAGS([audioqueue], [-Wl,-framework,AudioToolbox,-framework,CoreFoundation])
+fi
+
+dnl
 dnl  Roku HD1000 audio
 dnl
 AC_ARG_ENABLE(hd1000a,
diff --git a/modules/audio_output/Modules.am b/modules/audio_output/Modules.am
index f9df5bd..ce0f478 100644
--- a/modules/audio_output/Modules.am
+++ b/modules/audio_output/Modules.am
@@ -8,6 +8,7 @@ SOURCES_portaudio = portaudio.c
 SOURCES_auhal = auhal.c
 SOURCES_jack = jack.c
 SOURCES_pulse = pulse.c
+SOURCES_audioqueue = audioqueue.c
 
 libvlc_LTLIBRARIES += libaout_file_plugin.la
 
diff --git a/modules/audio_output/audioqueue.c b/modules/audio_output/audioqueue.c
new file mode 100644
index 0000000..e7427b8
--- /dev/null
+++ b/modules/audio_output/audioqueue.c
@@ -0,0 +1,175 @@
+/*****************************************************************************
+ * audioqueue.c : AudioQueue audio output plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2010 VideoLAN and AUTHORS
+ *
+ * Authors: Romain Goyet <romain.goyet at likid.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <unistd.h>                                      /* write(), close() */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_aout.h>
+
+#include <AudioToolBox/AudioToolBox.h>
+
+#define FRAME_SIZE 2048
+#define NUMBER_OF_BUFFERS 3
+
+/*****************************************************************************
+ * aout_sys_t: AudioQueue audio output method descriptor
+ *****************************************************************************
+ * This structure is part of the audio output thread descriptor.
+ * It describes the specific properties of an audio device.
+ *****************************************************************************/
+struct aout_sys_t
+{
+    AudioQueueRef audioQueue;
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  Open               ( vlc_object_t * );
+static void Close              ( vlc_object_t * );
+static void Play               ( aout_instance_t * );
+static void AudioQueueCallback (void *, AudioQueueRef, AudioQueueBufferRef);
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin ()
+    set_shortname( "AudioQueue" )
+    set_description( N_("AudioQueue (iOS / Mac OS) audio output") )
+    set_capability( "audio output", 40 )
+    set_category( CAT_AUDIO )
+    set_subcategory( SUBCAT_AUDIO_AOUT )
+    add_shortcut( "audioqueue" )
+    set_callbacks( Open, Close )
+vlc_module_end ()
+
+/*****************************************************************************
+ * Open: open the audio device
+ *****************************************************************************/
+
+static int Open ( vlc_object_t *p_this )
+{
+    aout_instance_t *p_aout = (aout_instance_t *)p_this;
+    struct aout_sys_t *p_sys = malloc(sizeof(aout_sys_t));
+    p_aout->output.p_sys = p_sys;
+
+    OSStatus status = 0;
+
+    // Setup the audio device.
+    AudioStreamBasicDescription deviceFormat;
+    deviceFormat.mSampleRate = 44100;
+    deviceFormat.mFormatID = kAudioFormatLinearPCM;
+    deviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; // Signed integer, little endian
+    deviceFormat.mBytesPerPacket = 4;
+    deviceFormat.mFramesPerPacket = 1;
+    deviceFormat.mBytesPerFrame = 4;
+    deviceFormat.mChannelsPerFrame = 2;
+    deviceFormat.mBitsPerChannel = 16;
+    deviceFormat.mReserved = 0;
+
+    // Create a new output AudioQueue for the device.
+    status = AudioQueueNewOutput(&deviceFormat,         // Format
+                                 AudioQueueCallback,    // Callback
+                                 p_aout,                // User data, passed to the callback
+                                 CFRunLoopGetMain(),    // RunLoop
+                                 kCFRunLoopDefaultMode, // RunLoop mode
+                                 0,                     // Flags ; must be zero (per documentation)...
+                                 &(p_sys->audioQueue)); // Output
+
+    // This will be used for boosting the audio without the need of a mixer (floating-point conversion is expensive on ARM)
+    // AudioQueueSetParameter(p_sys->audioQueue, kAudioQueueParam_Volume, 12.0); // Defaults to 1.0
+
+    msg_Dbg(p_aout, "New AudioQueue output created (status = %ld)", status);
+
+    // Allocate buffers for the AudioQueue, and pre-fill them.
+    for (int i = 0; i < NUMBER_OF_BUFFERS; ++i) {
+        AudioQueueBufferRef buffer = NULL;
+        status = AudioQueueAllocateBuffer(p_sys->audioQueue, FRAME_SIZE * 4, &buffer);
+        AudioQueueCallback(NULL, p_sys->audioQueue, buffer);
+    }
+
+    /* Volume is entirely done in software. */
+    aout_VolumeSoftInit( p_aout );
+
+    p_aout->output.output.i_format = VLC_CODEC_S16L;
+    p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
+    p_aout->output.output.i_rate = 44100;
+    p_aout->output.i_nb_samples = FRAME_SIZE;
+    p_aout->output.pf_play = Play;
+
+    msg_Dbg(p_aout, "Starting AudioQueue (status = %ld)", status);
+    status = AudioQueueStart(p_sys->audioQueue, NULL);
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Play: play a sound samples buffer
+ *****************************************************************************/
+static void Play( aout_instance_t * p_aout )
+{
+    VLC_UNUSED(p_aout);
+}
+
+/*****************************************************************************
+ * Close: close the audio device
+ *****************************************************************************/
+static void Close ( vlc_object_t *p_this )
+{
+    aout_instance_t *p_aout = (aout_instance_t *)p_this;
+    struct aout_sys_t * p_sys = p_aout->output.p_sys;
+
+    msg_Dbg(p_aout, "Stopping AudioQueue");
+    AudioQueueStop(p_sys->audioQueue, false);
+    msg_Dbg(p_aout, "Disposing of AudioQueue");
+    AudioQueueDispose(p_sys->audioQueue, false);
+    free (p_sys);
+}
+
+void AudioQueueCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
+    aout_instance_t * p_aout = (aout_instance_t *)inUserData;
+    aout_buffer_t *   p_buffer = NULL;
+
+    if (p_aout) {
+        vlc_mutex_lock( &p_aout->output_fifo_lock );
+        p_buffer = aout_FifoPop( p_aout, &p_aout->output.fifo );
+        vlc_mutex_unlock( &p_aout->output_fifo_lock );
+    }
+
+    if ( p_buffer != NULL ) {
+        vlc_memcpy( inBuffer->mAudioData, p_buffer->p_buffer, p_buffer->i_buffer );
+        inBuffer->mAudioDataByteSize = p_buffer->i_buffer;
+        aout_BufferFree( p_buffer );
+    } else {
+        vlc_memset( inBuffer->mAudioData, 0, inBuffer->mAudioDataBytesCapacity );
+        inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
+    }
+    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
+}



More information about the vlc-commits mailing list