]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[unit-tests] [mod_sndfile] parallelize unit-tests, each audio extension test in its... 1298/head
authorDragos Oancea <dragos@signalwire.com>
Mon, 18 May 2020 17:58:48 +0000 (18:58 +0100)
committerAndrey Volk <andywolk@gmail.com>
Mon, 9 Aug 2021 14:07:35 +0000 (17:07 +0300)
src/mod/formats/mod_sndfile/test/test_sndfile.c

index a9783ffa15e7ecda883f2cdb4e2abab288d74442..d2eb2b4f34407efc4b24842a8550efa307957f4f 100644 (file)
@@ -95,347 +95,496 @@ char *extensions[] = {
        "r32", "ul", "ulaw", "al", 
        "alaw", "gsm", "vox", "oga", "ogg"};
 
-FST_CORE_BEGIN("test_formats_and_muxing")
+static switch_thread_t *thread_list[sizeof(extensions) / sizeof(extensions[0])];
+
+static int duration = 3000; /*ms*/
+static int timeout_sec = 2; 
+
+typedef struct  {
+       char *ext; /*in*/
+       switch_status_t status; /*out*/
+       char *err_detail; /*out*/
+       switch_status_t jstatus;
+} test_params_t;
+
+#define thread_bail_out(x, msg) if (!x) {params->status = SWITCH_STATUS_FALSE; params->err_detail = strdup(msg); return NULL;}
+
+static void *SWITCH_THREAD_FUNC sndfile_write_read_mono_thread_run(switch_thread_t *thread, void *obj)
 {
-       FST_SUITE_BEGIN(test_sndfile)
-       {
-               FST_SETUP_BEGIN()
-               {
-                       fst_requires_module("mod_loopback");
-                       fst_requires_module("mod_sndfile");
-               }
-               FST_SETUP_END()
+       /* play mono, record mono, open mono */
+       test_params_t *params = (test_params_t *) obj;
+       switch_core_session_t *session = NULL;
+       switch_channel_t *channel = NULL;
+       switch_status_t status;
+       switch_call_cause_t cause;
+       static char play_filename[] = "../sounds/hi.wav";
+       char path[4096];
+       switch_file_handle_t fh = { 0 };
+       int16_t *audiobuf;
+       switch_size_t len;
+       switch_size_t rd;
+       char *recording;
 
-               FST_TEARDOWN_BEGIN()
-               {
-               }
-               FST_TEARDOWN_END()
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started thread [%lu] Testing media file extension: [%s]\n", switch_thread_self(), params->ext);
 
-               FST_TEST_BEGIN(sndfile_write_read_mono)
-               {
-                       /* play mono, record mono, open mono */
-                       switch_core_session_t *session = NULL;
-                       switch_channel_t *channel = NULL;
-                       switch_status_t status;
-                       switch_call_cause_t cause;
-                       static char play_filename[] = "../sounds/hi.wav";
-                       char path[4096];
-                       switch_file_handle_t fh = { 0 };
-                       int16_t *audiobuf;
-                       switch_size_t len, rd;
-                       char *recording;
-                       int i, exlen, timeout_sec = 2, duration = 3000; /*ms*/
-                       switch_stream_handle_t stream = { 0 };
+       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
 
-                       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
+       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
+       thread_bail_out(session, "no session");
+       
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_originate() status != SWITCH_STATUS_SUCCESS");
 
-                       SWITCH_STANDARD_STREAM(stream);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", params->ext);
 
-                       switch_api_execute("sndfile_debug", "on", session, &stream);
+       recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), params->ext);
+       status = switch_ivr_record_session(session, recording, duration, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_record_session() status != SWITCH_STATUS_SUCCESS");
 
-                       switch_safe_free(stream.data);
+       status = switch_ivr_play_file(session, NULL, path, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_play_file() status != SWITCH_STATUS_SUCCESS");
 
-                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
+       switch_sleep(1000 * duration); // wait for audio to finish playing
 
-                       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
-                       fst_requires(session);
-                       fst_check(status == SWITCH_STATUS_SUCCESS);
+       switch_ivr_stop_record_session(session, "all");
 
-                       for (i = 0; i < exlen; i++) {
+       status = switch_core_file_open(&fh, recording, 1, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_open() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
+       rd = 320; // samples
+       len = rd * sizeof(*audiobuf);
+       switch_zmalloc(audiobuf, len);
 
-                               recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
-                               status = switch_ivr_record_session(session, recording, duration, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       status = switch_core_file_read(&fh, audiobuf, &rd);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_read() status != SWITCH_STATUS_SUCCESS");
 
-                               status = switch_ivr_play_file(session, NULL, path, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       thread_bail_out((rd == 320), " rd != 320 "); // check that we read the wanted number of samples
 
-                               switch_sleep(1000 * duration); // wait for audio to finish playing
+       status = switch_core_file_close(&fh);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_close() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_ivr_stop_record_session(session, "all");
+       switch_safe_free(audiobuf);
 
-                               status = switch_core_file_open(&fh, recording, 1, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       unlink(recording);
 
-                               rd = 320; // samples
-                               len = rd * sizeof(*audiobuf);
-                               switch_zmalloc(audiobuf, len);
+       switch_safe_free(recording);
 
-                               status = switch_core_file_read(&fh, audiobuf, &rd);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
-                               fst_check(rd = 320); // check that we read the wanted number of samples
+       switch_sleep(1000000);
 
-                               status = switch_core_file_close(&fh);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       channel = switch_core_session_get_channel(session);
+       thread_bail_out(channel, "switch_core_session_get_channel() channel should not be NULL");
 
-                               switch_safe_free(audiobuf);
+       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+       thread_bail_out(!switch_channel_ready(channel), "switch_channel_ready(channel) should not return TRUE")
 
-                               unlink(recording);
+       switch_core_session_rwunlock(session);
 
-                               switch_safe_free(recording);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Finished thread [%lu]\n", switch_thread_self());
 
-                               switch_sleep(1000000);
-                       }
+       return NULL;
+}
 
-                       channel = switch_core_session_get_channel(session);
-                       fst_requires(channel);
 
-                       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                       fst_check(!switch_channel_ready(channel));
+static void *SWITCH_THREAD_FUNC sndfile_write_read_m2s_thread_run(switch_thread_t *thread, void *obj)
+{
+       /* play mono file, record mono, open stereo */
+       test_params_t *params = (test_params_t *) obj;
+       switch_core_session_t *session = NULL;
+       switch_channel_t *channel = NULL;
+       switch_status_t status;
+       switch_call_cause_t cause;
+       static char play_filename[] = "../sounds/hi.wav";
+       char path[4096];
+       switch_file_handle_t fh = { 0 };
+       int16_t *audiobuf;
+       switch_size_t len, rd;
+       char *recording;
+       int channels = 2;
 
-                       switch_core_session_rwunlock(session);
-               }
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started thread [%lu] Testing media file extension: [%s]\n", switch_thread_self(), params->ext);
 
-               FST_TEST_END()
+       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
 
-               FST_TEST_BEGIN(sndfile_write_read_m2s)
-               {
-                       /* play mono file, record mono, open stereo */
-                       switch_core_session_t *session = NULL;
-                       switch_channel_t *channel = NULL;
-                       switch_status_t status;
-                       switch_call_cause_t cause;
-                       static char play_filename[] = "../sounds/hi.wav";
-                       char path[4096];
-                       switch_file_handle_t fh = { 0 };
-                       int16_t *audiobuf;
-                       switch_size_t len, rd;
-                       char *recording;
-                       int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
-                       switch_stream_handle_t stream = { 0 };
-               
-                       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
+       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_originate() status != SWITCH_STATUS_SUCCESS");
 
-                       SWITCH_STANDARD_STREAM(stream);
+       recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), params->ext);
 
-                       switch_api_execute("sndfile_debug", "on", session, &stream);
+       status = switch_ivr_record_session(session, recording, duration, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_record_session() status != SWITCH_STATUS_SUCCESS");
 
-                       switch_safe_free(stream.data);
+       status = switch_ivr_play_file(session, NULL, path, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_play_file() status != SWITCH_STATUS_SUCCESS");
 
-                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
+       switch_sleep(1000 * duration); // wait for audio to finish playing
 
-                       for (i = 0; i < exlen; i++) {
+       switch_ivr_stop_record_session(session, "all");
 
-                               status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
-                               fst_requires(session);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       channel = switch_core_session_get_channel(session);
+       thread_bail_out(channel, "switch_core_session_get_channel() channel should not be NULL");
 
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
+       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+       thread_bail_out(!switch_channel_ready(channel), "switch_channel_ready(channel) should not return TRUE")
 
-                               recording = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
+       switch_core_session_rwunlock(session);
 
-                               status = switch_ivr_record_session(session, recording, duration, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_open() status != SWITCH_STATUS_SUCCESS");
 
-                               status = switch_ivr_play_file(session, NULL, path, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       rd = 320; // samples
+       len = rd * sizeof(*audiobuf) * channels;
+       switch_zmalloc(audiobuf, len);
 
-                               switch_sleep(1000 * duration); // wait for audio to finish playing
+       status = switch_core_file_read(&fh, audiobuf, &rd);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_read() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_ivr_stop_record_session(session, "all");
+       thread_bail_out((rd == 320), " rd != 320 "); // check that we read the wanted number of samples
 
-                               channel = switch_core_session_get_channel(session);
-                               fst_requires(channel);
+       status = switch_core_file_close(&fh);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_close() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                               fst_check(!switch_channel_ready(channel));
+       switch_safe_free(audiobuf);
 
-                               switch_core_session_rwunlock(session);
+       unlink(recording);
 
-                               status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       switch_safe_free(recording);
 
-                               rd = 320; // samples
-                               len = rd * sizeof(*audiobuf) * channels;
-                               switch_zmalloc(audiobuf, len);
+       switch_sleep(1000000);
 
-                               status = switch_core_file_read(&fh, audiobuf, &rd);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
-                               fst_check(rd = 320); // check that we read the wanted number of samples
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Finished thread [%lu]\n", switch_thread_self());
 
-                               status = switch_core_file_close(&fh);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       return NULL;
+}
 
-                               switch_safe_free(audiobuf);
+static void *SWITCH_THREAD_FUNC sndfile_write_read_s2m_thread_run(switch_thread_t *thread, void *obj)
+{
+       /* play stereo wav, record stereo, open stereo file */
+       test_params_t *params = (test_params_t *) obj;
+       switch_core_session_t *session = NULL;
+       switch_channel_t *channel = NULL;
+       switch_status_t status;
+       switch_call_cause_t cause;
+       static char play_filename[] = "../sounds/hello_stereo.wav";
+       char path[4096];
+       switch_file_handle_t fh = { 0 };
+       int16_t *audiobuf;
+       switch_size_t len, rd;
+       char *recording, *rec_path;
+       int channels = 2; 
 
-                               unlink(recording);
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started thread [%lu] Testing media file extension: [%s]\n", switch_thread_self(), params->ext);
 
-                               switch_safe_free(recording);
+       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
 
-                               switch_sleep(1000000);
-                       }
-               }
-               FST_TEST_END()
+       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_originate() status != SWITCH_STATUS_SUCCESS");
 
-               FST_TEST_BEGIN(sndfile_write_read_s2m)
-               {
-                       /* play stereo wav, record stereo, open stereo file */
-                       switch_core_session_t *session = NULL;
-                       switch_channel_t *channel = NULL;
-                       switch_status_t status;
-                       switch_call_cause_t cause;
-                       static char play_filename[] = "../sounds/hello_stereo.wav";
-                       char path[4096];
-                       switch_file_handle_t fh = { 0 };
-                       int16_t *audiobuf;
-                       switch_size_t len, rd;
-                       char *recording, *rec_path;
-                       int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
-                       switch_stream_handle_t stream = { 0 };
-                       
-                       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
+       rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), params->ext);
+       recording = switch_mprintf("{force_channels=2}%s", rec_path);
 
-                       SWITCH_STANDARD_STREAM(stream);
+       channel = switch_core_session_get_channel(session);
+       thread_bail_out(channel, "switch_core_session_get_channel() channel should not be NULL");
 
-                       switch_api_execute("sndfile_debug", "on", session, &stream);
+       switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
 
-                       switch_safe_free(stream.data);
+       status = switch_ivr_record_session(session, recording, duration, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_record_session() status != SWITCH_STATUS_SUCCESS");
 
-                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
+       status = switch_ivr_play_file(session, NULL, path, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_play_file() status != SWITCH_STATUS_SUCCESS");
 
-                       for (i = 0; i < exlen; i++) {
+       switch_sleep(1000 * duration); // wait for audio to finish playing
+
+       switch_ivr_stop_record_session(session, "all");
+
+       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+       thread_bail_out(!switch_channel_ready(channel), "switch_channel_ready(channel) should not return TRUE")
+
+       switch_core_session_rwunlock(session);
+
+       status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_open() status != SWITCH_STATUS_SUCCESS");
+
+       rd = 320; // samples
+       len = rd * sizeof(*audiobuf) * channels;
+       switch_zmalloc(audiobuf, len);
+
+       status = switch_core_file_read(&fh, audiobuf, &rd);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_read() status != SWITCH_STATUS_SUCCESS");
 
-                               status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
+       thread_bail_out((rd == 320), " rd != 320 "); // check that we read the wanted number of samples
 
-                               fst_requires(session);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       status = switch_core_file_close(&fh);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_close() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
+       switch_safe_free(audiobuf);
 
-                               rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
-                               recording = switch_mprintf("{force_channels=2}%s", rec_path);
+       unlink(rec_path);
 
-                               channel = switch_core_session_get_channel(session);
-                               fst_requires(channel);
+       switch_safe_free(rec_path);
+       switch_safe_free(recording);
 
-                               switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
+       switch_sleep(1000000);
 
-                               status = switch_ivr_record_session(session, recording, duration, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       return NULL;
+}
+
+static void *SWITCH_THREAD_FUNC sndfile_write_read_stereo_thread_run(switch_thread_t *thread, void *obj)
+{
+       /* play stereo wav, record stereo, open stereo file */
+       test_params_t *params = (test_params_t *) obj;
+       switch_core_session_t *session = NULL;
+       switch_channel_t *channel = NULL;
+       switch_status_t status;
+       switch_call_cause_t cause;
+       static char play_filename[] = "../sounds/hello_stereo.wav";
+       char path[4096];
+       switch_file_handle_t fh = { 0 };
+       int16_t *audiobuf;
+       switch_size_t len, rd;
+       char *recording, *rec_path;
+       int channels = 2; 
+       
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started thread [%lu] Testing media file extension: [%s]\n", switch_thread_self(), params->ext);
+
+       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
+
+       status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_play_file() status != SWITCH_STATUS_SUCCESS");
+
+       rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), params->ext);
+       recording = switch_mprintf("{force_channels=2}%s", rec_path);
+
+       channel = switch_core_session_get_channel(session);
+       thread_bail_out(channel, "switch_core_session_get_channel() channel should not be NULL");
+
+       switch_channel_set_variable(channel, "RECORD_STEREO", "true");
+       switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
+
+       status = switch_ivr_record_session(session, recording, duration, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_record_session() status != SWITCH_STATUS_SUCCESS");
 
-                               status = switch_ivr_play_file(session, NULL, path, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+       status = switch_ivr_play_file(session, NULL, path, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_ivr_play_file() status != SWITCH_STATUS_SUCCESS");
 
-                               switch_sleep(1000 * duration); // wait for audio to finish playing
+       switch_sleep(1000 * duration); // wait for audio to finish playing
 
-                               switch_ivr_stop_record_session(session, "all");
+       switch_ivr_stop_record_session(session, "all");
 
-                               switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                               fst_check(!switch_channel_ready(channel));
+       switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+       thread_bail_out(!switch_channel_ready(channel), "switch_channel_ready(channel) should not return TRUE")
 
-                               switch_core_session_rwunlock(session);
+       switch_core_session_rwunlock(session);
 
-                               status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_open() status != SWITCH_STATUS_SUCCESS");
 
-                               rd = 320; // samples
-                               len = rd * sizeof(*audiobuf) * channels;
-                               switch_zmalloc(audiobuf, len);
+       rd = 320; // samples
+       len = rd * sizeof(*audiobuf) * channels;
+       switch_zmalloc(audiobuf, len);
 
-                               status = switch_core_file_read(&fh, audiobuf, &rd);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
-                               fst_check(rd = 320); // check that we read the wanted number of samples
+       status = switch_core_file_read(&fh, audiobuf, &rd);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_read() status != SWITCH_STATUS_SUCCESS");
 
-                               status = switch_core_file_close(&fh);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+       thread_bail_out((rd == 320), " rd != 320 "); // check that we read the wanted number of samples
 
-                               switch_safe_free(audiobuf);
+       status = switch_core_file_close(&fh);
+       thread_bail_out(status == SWITCH_STATUS_SUCCESS, "switch_core_file_close() status != SWITCH_STATUS_SUCCESS");
 
-                               unlink(rec_path);
+       switch_safe_free(audiobuf);
 
-                               switch_safe_free(rec_path);
-                               switch_safe_free(recording);
+       unlink(rec_path);
 
-                               switch_sleep(1000000);
+       switch_safe_free(rec_path);
+       switch_safe_free(recording);
+
+       switch_sleep(1000000);
+
+       return NULL;
+}
+
+FST_CORE_BEGIN("test_formats_and_muxing")
+{
+       FST_SUITE_BEGIN(test_sndfile)
+       {
+               FST_SETUP_BEGIN()
+               {
+                       fst_requires_module("mod_loopback");
+                       fst_requires_module("mod_sndfile");
+               }
+               FST_SETUP_END()
+
+               FST_TEARDOWN_BEGIN()
+               {
+               }
+               FST_TEARDOWN_END()
+
+               FST_TEST_BEGIN(sndfile_write_read_mono)
+               {
+                       int i, exlen; 
+                       switch_stream_handle_t stream = { 0 };
+                       test_params_t params[(sizeof(extensions) / sizeof(extensions[0]))] = { 0 };
+
+                       SWITCH_STANDARD_STREAM(stream);
+
+                       switch_api_execute("sndfile_debug", "on", NULL, &stream);
+
+                       switch_safe_free(stream.data);
+
+                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
+
+                       for (i = 0; i < exlen; i++) {
+                               switch_threadattr_t *thd_attr = NULL;
+
+                               params[i].ext = extensions[i];
+                               switch_threadattr_create(&thd_attr, fst_pool);
+                               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                               // slow down to avoid this:  "[CRIT] switch_time.c:1243 Over Session Rate of 30!"
+                               switch_thread_create(&thread_list[i], thd_attr, sndfile_write_read_mono_thread_run, (void *)&params[i], fst_pool);
+                               switch_sleep(100000);
+                       }
+
+                       for (i = 0; i < exlen; i++) {
+                               switch_thread_join(&params[i].jstatus, thread_list[i]);
+                               fst_requires(params[i].jstatus == SWITCH_STATUS_SUCCESS);
+                       }
+
+                       for (i = 0; i < exlen; i++) {
+                               if (params[i].err_detail) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Extension [%s] Result: [%s]\n", extensions[i], params[i].err_detail);
+                                       switch_safe_free(params[i].err_detail);
+                               }
+                               fst_requires(params[i].status == SWITCH_STATUS_SUCCESS);
                        }
+                       switch_sleep(1000000);
+
                }
 
                FST_TEST_END()
 
-               FST_TEST_BEGIN(sndfile_write_read_stereo)
+               FST_TEST_BEGIN(sndfile_write_read_m2s)
                {
-                       /* play stereo wav, record stereo, open stereo file */
-                       switch_core_session_t *session = NULL;
-                       switch_channel_t *channel = NULL;
-                       switch_status_t status;
-                       switch_call_cause_t cause;
-                       static char play_filename[] = "../sounds/hello_stereo.wav";
-                       char path[4096];
-                       switch_file_handle_t fh = { 0 };
-                       int16_t *audiobuf;
-                       switch_size_t len, rd;
-                       char *recording, *rec_path;
-                       int i, exlen, channels = 2, timeout_sec = 2, duration = 3000; /*ms*/
+                       int i, exlen;
                        switch_stream_handle_t stream = { 0 };
-                       
-                       sprintf(path, "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, play_filename);
+                       test_params_t params[(sizeof(extensions) / sizeof(extensions[0]))] = { 0 };
 
                        SWITCH_STANDARD_STREAM(stream);
 
-                       switch_api_execute("sndfile_debug", "on", session, &stream);
+                       switch_api_execute("sndfile_debug", "on", NULL, &stream);
 
                        switch_safe_free(stream.data);
 
                        exlen = (sizeof(extensions) / sizeof(extensions[0]));
 
                        for (i = 0; i < exlen; i++) {
+                               switch_threadattr_t *thd_attr = NULL;
+
+                               params[i].ext = extensions[i];
+                               switch_threadattr_create(&thd_attr, fst_pool);
+                               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                               // slow down to avoid this:  "[CRIT] switch_time.c:1243 Over Session Rate of 30!"
+                               switch_thread_create(&thread_list[i], thd_attr, sndfile_write_read_m2s_thread_run, (void *)&params[i], fst_pool);
+                               switch_sleep(100000);
+                       }
+
+                       for (i = 0; i < exlen; i++) {
+                               switch_thread_join(&params[i].jstatus, thread_list[i]);
+                               fst_requires(params[i].jstatus == SWITCH_STATUS_SUCCESS);
+                       }
 
-                               status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", timeout_sec, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
-                               fst_requires(session);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+                       for (i = 0; i < exlen; i++) {
+                               if (params[i].err_detail) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Extension [%s] Result: [%s]\n", extensions[i], params[i].err_detail);
+                                       switch_safe_free(params[i].err_detail);
+                               }
+                               fst_requires(params[i].status == SWITCH_STATUS_SUCCESS);
+                       }
+                       switch_sleep(1000000);
+               }
+               FST_TEST_END()
 
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Testing media file extension: [%s]\n", extensions[i]);
+               FST_TEST_BEGIN(sndfile_write_read_s2m)
+               {
+                       int i, exlen; 
+                       switch_stream_handle_t stream = { 0 };
+                       test_params_t params[(sizeof(extensions) / sizeof(extensions[0]))] = { 0 };
+                       
+                       SWITCH_STANDARD_STREAM(stream);
 
-                               rec_path = switch_mprintf("/tmp/%s.%s", switch_core_session_get_uuid(session), extensions[i]);
-                               recording = switch_mprintf("{force_channels=2}%s", rec_path);
+                       switch_api_execute("sndfile_debug", "on", NULL, &stream);
 
-                               channel = switch_core_session_get_channel(session);
-                               fst_requires(channel);
+                       switch_safe_free(stream.data);
 
-                               switch_channel_set_variable(channel, "RECORD_STEREO", "true");
-                               switch_channel_set_variable(channel, "enable_file_write_buffering", "true");
+                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
 
-                               status = switch_ivr_record_session(session, recording, duration, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+                       for (i = 0; i < exlen; i++) {
+                               switch_threadattr_t *thd_attr = NULL;
 
-                               status = switch_ivr_play_file(session, NULL, path, NULL);
-                               fst_check(status == SWITCH_STATUS_SUCCESS);
+                               params[i].ext = extensions[i];
+                               switch_threadattr_create(&thd_attr, fst_pool);
+                               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                               // slow down to avoid this:  "[CRIT] switch_time.c:1243 Over Session Rate of 30!"
+                               switch_thread_create(&thread_list[i], thd_attr, sndfile_write_read_s2m_thread_run, (void *)&params[i], fst_pool);
+                               switch_sleep(10000);
 
-                               switch_sleep(1000 * duration); // wait for audio to finish playing
+                       }
 
-                               switch_ivr_stop_record_session(session, "all");
+                       for (i = 0; i < exlen; i++) {
+                               switch_thread_join(&params[i].jstatus, thread_list[i]);
+                               fst_requires(params[i].jstatus == SWITCH_STATUS_SUCCESS);
+                       }
 
-                               switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-                               fst_check(!switch_channel_ready(channel));
+                       for (i = 0; i < exlen; i++) {
+                               if (params[i].err_detail) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Extension [%s] Result: [%s]\n", extensions[i], params[i].err_detail);
+                                       switch_safe_free(params[i].err_detail);
+                               }
+                               fst_requires(params[i].status == SWITCH_STATUS_SUCCESS);
+                       }
+                       switch_sleep(1000000);
+               }
 
-                               switch_core_session_rwunlock(session);
+               FST_TEST_END()
 
-                               status = switch_core_file_open(&fh, recording, channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+               FST_TEST_BEGIN(sndfile_write_read_stereo)
+               {
+                       int i, exlen; 
+                       switch_stream_handle_t stream = { 0 };
+                       test_params_t params[(sizeof(extensions) / sizeof(extensions[0]))] = { 0 };
 
-                               rd = 320; // samples
-                               len = rd * sizeof(*audiobuf) * channels;
-                               switch_zmalloc(audiobuf, len);
+                       SWITCH_STANDARD_STREAM(stream);
 
-                               status = switch_core_file_read(&fh, audiobuf, &rd);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
-                               fst_check(rd = 320); // check that we read the wanted number of samples
+                       switch_api_execute("sndfile_debug", "on", NULL, &stream);
 
-                               status = switch_core_file_close(&fh);
-                               fst_requires(status == SWITCH_STATUS_SUCCESS);
+                       switch_safe_free(stream.data);
 
-                               switch_safe_free(audiobuf);
+                       exlen = (sizeof(extensions) / sizeof(extensions[0]));
 
-                               unlink(rec_path);
+                       for (i = 0; i < exlen; i++) {
+                               switch_threadattr_t *thd_attr = NULL;
+
+                               params[i].ext = extensions[i];
+                               switch_threadattr_create(&thd_attr, fst_pool);
+                               switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+                               // slow down to avoid this:  "[CRIT] switch_time.c:1243 Over Session Rate of 30!"
+                               switch_thread_create(&thread_list[i], thd_attr, sndfile_write_read_stereo_thread_run, (void *)&params[i], fst_pool);
+                               switch_sleep(100000);
+                       }
 
-                               switch_safe_free(rec_path);
-                               switch_safe_free(recording);
+                       for (i = 0; i < exlen; i++) {
+                               switch_thread_join(&params[i].jstatus, thread_list[i]);
+                               fst_requires(params[i].jstatus == SWITCH_STATUS_SUCCESS);
+                       }
 
-                               switch_sleep(1000000);
+                       for (i = 0; i < exlen; i++) {
+                               if (params[i].err_detail) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Extension [%s] Result: [%s]\n", extensions[i], params[i].err_detail);
+                                       switch_safe_free(params[i].err_detail);
+                               }
+                               fst_requires(params[i].status == SWITCH_STATUS_SUCCESS);
                        }
+                       switch_sleep(1000000);
                }
+
                FST_TEST_END()
 
                FST_TEST_BEGIN(unload_mod_sndfile)