diff --git a/dynamic.c b/dynamic.c
index 0a479c59af..cbf2245b6f 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -289,6 +289,8 @@ void dylib_close(dylib_t lib)
 }
 #endif
 
+unsigned audio_sample_batch(const int16_t *, unsigned);
+
 #if defined(NEED_DYNAMIC) || defined(SSNES_CONSOLE)
 static bool environment_cb(unsigned cmd, void *data)
 {
@@ -410,6 +412,11 @@ static bool environment_cb(unsigned cmd, void *data)
          break;
       }
 
+      case SNES_ENVIRONMENT_GET_AUDIO_BATCH_CB:
+         SSNES_LOG("Environ GET_AUDIO_BATCH_CB\n");
+         *(snes_audio_sample_batch_t*)data = audio_sample_batch;
+         break;
+
       default:
          SSNES_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
          return false;
diff --git a/libsnes.hpp b/libsnes.hpp
index 4227af09d2..dffcaeca02 100755
--- a/libsnes.hpp
+++ b/libsnes.hpp
@@ -126,6 +126,11 @@ extern "C" {
                                                 //
 #define SNES_ENVIRONMENT_SET_MESSAGE 12         // const struct snes_message * --
                                                 // Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'.
+                                                //
+#define SNES_ENVIRONMENT_GET_AUDIO_BATCH_CB 13  // snes_audio_sample_batch_t * --
+                                                // Retrieves callback to a more optimized audio callback.
+
+
 
 struct snes_message
 {
@@ -164,6 +169,10 @@ void snes_set_environment(snes_environment_t);
 
 typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height);
 typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
+
+// Performance extension. Retrieved from environ callback.
+typedef unsigned (*snes_audio_sample_batch_t)(const int16_t *data, unsigned frames);
+
 typedef void (*snes_input_poll_t)(void);
 typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id);
 
diff --git a/ssnes.c b/ssnes.c
index e784182808..d5b97b584a 100644
--- a/ssnes.c
+++ b/ssnes.c
@@ -390,6 +390,28 @@ static void audio_sample(uint16_t left, uint16_t right)
    g_extern.audio_data.data_ptr = 0;
 }
 
+// Non-standard, alternative callback better suited for systems that process audio in batch.
+// Avoids tons of calls to audio_sample() ...
+unsigned audio_sample_batch(const int16_t *data, unsigned frames)
+{
+   if (frames > (AUDIO_CHUNK_SIZE_NONBLOCKING >> 1))
+      frames = AUDIO_CHUNK_SIZE_NONBLOCKING >> 1;
+
+   memcpy(g_extern.audio_data.conv_outsamples,
+         data, (frames << 1) * sizeof(int16_t));
+   g_extern.audio_data.data_ptr = frames << 1;
+
+   if (g_extern.audio_data.data_ptr >= g_extern.audio_data.chunk_size)
+   {
+      g_extern.audio_active = audio_flush(g_extern.audio_data.conv_outsamples,
+            g_extern.audio_data.data_ptr) && g_extern.audio_active;
+
+      g_extern.audio_data.data_ptr = 0;
+   }
+
+   return frames;
+}
+
 static void input_poll(void)
 {
    driver.input->poll(driver.input_data);