diff --git a/UPGRADE b/UPGRADE
index b100e0c1..0c804212 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -602,6 +602,9 @@ OTHER CHANGES:
throttling if set to an audible sound at a 20 second interval. Tested
with the 'click_quiet' sound file at a volume of '25'.
+169. Added WAV audio file validation for Audio Store, and display of badly
+ formatted WAV files in the audio chooser in admin.php
+
diff --git a/docs/NON-AGENT_API.txt b/docs/NON-AGENT_API.txt
index 22252b0d..22d90a51 100644
--- a/docs/NON-AGENT_API.txt
+++ b/docs/NON-AGENT_API.txt
@@ -1,4 +1,4 @@
-NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2021-03-20
+NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2021-03-22
This document describes the functions of an API(Application Programming
Interface) for all functions NOT directly relating to the VICIDIAL Agent screen.
@@ -180,6 +180,7 @@ Changes:
210316-2207 - Added lead_all_info function
210319-1720 - Added special 'xDAYS' value option for callback_datetime
210320-2127 - Added 'custom_fields_add' option for update_list function
+210322-1218 - Added display of bad wav file formats on sounds_list function
API Functions use the 'function' variable
diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql
index ab99fd1f..8f11128e 100644
--- a/extras/MySQL_AST_CREATE_tables.sql
+++ b/extras/MySQL_AST_CREATE_tables.sql
@@ -3440,6 +3440,8 @@ audio_format VARCHAR(10) default 'unknown',
audio_filesize BIGINT(20) UNSIGNED default '0',
audio_epoch BIGINT(20) UNSIGNED default '0',
audio_length INT(10) UNSIGNED default '0',
+wav_format_details VARCHAR(255) default '',
+wav_asterisk_valid ENUM('','GOOD','BAD','NA') default '',
unique index (audio_filename)
) ENGINE=MyISAM;
@@ -4869,4 +4871,4 @@ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_
UPDATE system_settings set vdc_agent_api_active='1';
-UPDATE system_settings SET db_schema_version='1624',db_schema_update_date=NOW(),reload_timestamp=NOW();
+UPDATE system_settings SET db_schema_version='1625',db_schema_update_date=NOW(),reload_timestamp=NOW();
diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql
index af037f4d..b24adc15 100644
--- a/extras/upgrade_2.14.sql
+++ b/extras/upgrade_2.14.sql
@@ -1594,3 +1594,8 @@ ALTER TABLE quality_control_checkpoint_log ADD checkpoint_text_presets TEXT AFTE
ALTER TABLE quality_control_checkpoints ADD checkpoint_text_presets TEXT AFTER checkpoint_text;
UPDATE system_settings SET db_schema_version='1624',db_schema_update_date=NOW() where db_schema_version < 1624;
+
+ALTER TABLE audio_store_details ADD wav_format_details VARCHAR(255) default '';
+ALTER TABLE audio_store_details ADD wav_asterisk_valid ENUM('','GOOD','BAD','NA') default '';
+
+UPDATE system_settings SET db_schema_version='1625',db_schema_update_date=NOW() where db_schema_version < 1625;
diff --git a/www/vicidial/audio_store.php b/www/vicidial/audio_store.php
index 9c7805f5..cf070b53 100644
--- a/www/vicidial/audio_store.php
+++ b/www/vicidial/audio_store.php
@@ -32,15 +32,17 @@
# 180618-2300 - Modified calls to audio file chooser function
# 201002-1536 - Allowed for secure sounds_web_server setting
# 210321-0131 - Added classAudioFile PHP library for WAV file format validation
+# 210322-1220 - Added checking of .wav files for asterisk-compatible format
#
-$version = '2.14-24';
-$build = '210321-0131';
+$version = '2.14-25';
+$build = '210322-1220';
$MT[0]='';
require("dbconnect_mysqli.php");
require("functions.php");
+require ('classAudioFile.php');
$server_name = getenv("SERVER_NAME");
$PHP_SELF=$_SERVER['PHP_SELF'];
@@ -320,6 +322,112 @@ if ($action == "LIST")
}
+##### BEGIN go through all Audio Store WAV files and validate for asterisk compatibility #####
+$stmt = "SELECT count(*) FROM audio_store_details where audio_format='wav' and wav_asterisk_valid='';";
+$rslt=mysql_to_mysqli($stmt, $link);
+if ($DB) {echo "$stmt\n";}
+$wuv_ct = mysqli_num_rows($rslt);
+if ( ($wuv_ct > 0) or ($action == "ALL_WAV_VALIDATION") )
+ {
+ $i=0;
+ $filename_sort=$MT;
+ $dirpath = "$WeBServeRRooT/$sounds_web_directory";
+ $dh = opendir($dirpath);
+ while (false !== ($file = readdir($dh)))
+ {
+ # Do not list subdirectories
+ if ( (!is_dir("$dirpath/$file")) and (preg_match('/\.wav$|\.gsm$/', $file)) )
+ {
+ if (file_exists("$dirpath/$file"))
+ {
+ $file_names[$i] = $file;
+ $file_epoch[$i] = filemtime("$dirpath/$file");
+ $file_dates[$i] = date ("Y-m-d H:i:s.", filemtime("$dirpath/$file"));
+ $file_sizes[$i] = filesize("$dirpath/$file");
+ $filename_sort[$i] = $file . "----------" . $i . "----------" . $file_sizes[$i];
+ $i++;
+ }
+ }
+ }
+ closedir($dh);
+
+ sort($filename_sort);
+
+ sleep(1);
+
+ $wav_valid=0;
+ $wav_invalid=0;
+ $not_wav=0;
+ $k=0;
+ while($k < $i)
+ {
+ $filename_split = explode('----------',$filename_sort[$k]);
+ $m = $filename_split[1];
+ $size = $filename_split[2];
+ $audio_filesize = filesize("$dirpath/$file_names[$m]");
+ if ($size == $audio_filesize)
+ {
+ $audio_filename = $file_names[$m];
+ $audio_epoch = date("U");
+ $wav_format_details='';
+ $wav_asterisk_valid='NA';
+
+ if (preg_match("/\.wav$/", $audio_filename))
+ {
+ $audio_format='wav';
+ $audio_length = ($audio_filesize / 16000);
+
+ $AF = new AudioFile;
+ $AF->loadFile("$dirpath/$file_names[$m]");
+
+ $wav_type = $AF->wave_type;
+ $wav_compression = $AF->getCompression ($AF->wave_compression);
+ $wav_channels = $AF->wave_channels;
+ $wav_framerate = $AF->wave_framerate;
+ $wav_bits=$AF->wave_bits;
+ $audio_length=number_format ($AF->wave_length,"0");
+ $invalid_wav=0;
+
+ if (!preg_match('/^wav/i',$wav_type)) {$invalid_wav++;}
+ if (!preg_match('/^pcm/i',$wav_compression)) {$invalid_wav++;}
+ if ($wav_channels > 1) {$invalid_wav++;}
+ if ( ($wav_framerate > 8000) or ($wav_framerate < 8000) ) {$invalid_wav++;}
+ if ( ($wav_bits > 16) or ($wav_bits < 16) ) {$invalid_wav++;}
+
+ $wav_format_details = "$wav_type channels: $wav_channels framerate: $wav_framerate bits: $wav_bits length: $audio_length compression: $wav_compression";
+
+ if ($invalid_wav > 0)
+ {
+ $wav_asterisk_valid='BAD';
+ $wav_invalid++;
+ }
+ else
+ {
+ $wav_asterisk_valid='GOOD';
+ $wav_valid++;
+ }
+
+ $stmt="INSERT IGNORE INTO audio_store_details SET audio_filename='$audio_filename',audio_format='$audio_format',audio_filesize='$audio_filesize',audio_epoch='$audio_epoch',audio_length='$audio_length',wav_format_details='$wav_format_details',wav_asterisk_valid='$wav_asterisk_valid' ON DUPLICATE KEY UPDATE audio_filesize='$audio_filesize',audio_epoch='$audio_epoch',audio_length='$audio_length',wav_format_details='$wav_format_details',wav_asterisk_valid='$wav_asterisk_valid';";
+ if ($DB) {echo "|$stmt|\n";}
+ $rslt=mysql_to_mysqli($stmt, $link);
+ $affected_rowsX = mysqli_affected_rows($link);
+ }
+ else
+ {
+ $not_wav++;
+ }
+
+ if ($DB) {echo "$k\t$file_names[$m]\t$wav_asterisk_valid\n";}
+ }
+ $k++;
+ }
+
+ if ($DB) {echo "SUMMARY: WAV VALID: $wav_valid WAV INVALID: $wav_invalid NOT WAV: $not_wav\n";}
+ }
+##### END go through all Audio Store WAV files and validate for asterisk compatibility #####
+
+
+
### upload audio file from server to webserver
# curl 'http://10.0.0.4/vicidial/audio_store.php?action=AUTOUPLOAD' -F "audiofile=@/var/lib/asterisk/sounds/beep.gsm"
if ($action == "AUTOUPLOAD")
@@ -546,14 +654,22 @@ if ($action == "MANUALUPLOAD")
$audiofile_name = preg_replace("/\^/",'',$audiofile_name);
if (preg_match("/\.wav$|\.gsm$/", $audiofile_name))
{
+ $audio_epoch = date("U");
+ $audio_format='gsm';
+ $audio_filesize = filesize("$WeBServeRRooT/$sounds_web_directory/$audiofile_name");
+ $audio_length = ($audio_filesize / 1650);
+ $wav_format_details='';
+ $wav_asterisk_valid='NA';
+
copy($AF_path, "$WeBServeRRooT/$sounds_web_directory/$audiofile_name");
chmod("$WeBServeRRooT/$sounds_web_directory/$audiofile_name", 0766);
- echo "
"._QXZ("SUCCESS").": $audiofile_name "._QXZ("uploaded")." "._QXZ("size").":" . filesize("$WeBServeRRooT/$sounds_web_directory/$audiofile_name") . "
\n";
+ echo "
"._QXZ("SUCCESS").": $audiofile_name "._QXZ("uploaded")." "._QXZ("size").": $audio_filesize
\n";
if (preg_match("/\.wav$/", $audiofile_name))
{
- require ('classAudioFile.php');
+ $audio_format='wav';
+ $audio_length = ($audio_filesize / 16000);
$AF = new AudioFile;
$AF->loadFile("$WeBServeRRooT/$sounds_web_directory/$audiofile_name");
@@ -563,6 +679,7 @@ if ($action == "MANUALUPLOAD")
$wav_channels = $AF->wave_channels;
$wav_framerate = $AF->wave_framerate;
$wav_bits=$AF->wave_bits;
+ $audio_length=number_format ($AF->wave_length,"0");
$invalid_wav=0;
if (!preg_match('/^wav/i',$wav_type)) {$invalid_wav++;}
@@ -571,25 +688,35 @@ if ($action == "MANUALUPLOAD")
if ( ($wav_framerate > 8000) or ($wav_framerate < 8000) ) {$invalid_wav++;}
if ( ($wav_bits > 16) or ($wav_bits < 16) ) {$invalid_wav++;}
+ $wav_format_details = "$wav_type channels: $wav_channels framerate: $wav_framerate bits: $wav_bits length: $audio_length compression: $wav_compression";
+
if ($invalid_wav > 0)
{
+ $wav_asterisk_valid='BAD';
echo "
"._QXZ("INVALID WAV FILE FORMAT").": ($audiofile_name)
$wav_type "._QXZ("channels").": $wav_channels "._QXZ("framerate").": $wav_framerate "._QXZ("bits").": $wav_bits "._QXZ("compression").": $wav_compression
\n";
}
else
{
+ $wav_asterisk_valid='GOOD';
echo " "._QXZ("WAV FILE FORMAT VALIDATED").": $wav_type "._QXZ("channels").": $wav_channels "._QXZ("framerate").": $wav_framerate "._QXZ("bits").": $wav_bits "._QXZ("compression").": $wav_compression
\n";
}
echo "";
}
+ $stmt="INSERT IGNORE INTO audio_store_details SET audio_filename='$audiofile_name',audio_format='$audio_format',audio_filesize='$audio_filesize',audio_epoch='$audio_epoch',audio_length='$audio_length',wav_format_details='$wav_format_details',wav_asterisk_valid='$wav_asterisk_valid' ON DUPLICATE KEY UPDATE audio_filesize='$audio_filesize',audio_epoch='$audio_epoch',audio_length='$audio_length',wav_format_details='$wav_format_details',wav_asterisk_valid='$wav_asterisk_valid';";
+ if ($DB) {echo "|$stmt|\n";}
+ $rslt=mysql_to_mysqli($stmt, $link);
+ $affected_rowsX = mysqli_affected_rows($link);
+
$stmt="UPDATE servers SET sounds_update='Y';";
$rslt=mysql_to_mysqli($stmt, $link);
+ $affected_rowsY = mysqli_affected_rows($link);
### LOG INSERTION Admin Log Table ###
$SQL_log = "$stmt|";
$SQL_log = preg_replace('/;/', '', $SQL_log);
$SQL_log = addslashes($SQL_log);
- $stmt="INSERT INTO vicidial_admin_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$ip', event_section='AUDIOSTORE', event_type='LOAD', record_id='manualupload', event_code='$audiofile_name " . filesize("$WeBServeRRooT/$sounds_web_directory/$audiofile_name") . "', event_sql=\"$SQL_log\", event_notes='$audiofile_name $AF_path $AF_orig Invalid: $invalid_wav $wav_type "._QXZ("channels").": $wav_channels "._QXZ("framerate").": $wav_framerate "._QXZ("bits").": $wav_bits "._QXZ("compression").": $wav_compression';";
+ $stmt="INSERT INTO vicidial_admin_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$ip', event_section='AUDIOSTORE', event_type='LOAD', record_id='manualupload', event_code='$audiofile_name $audio_filesize', event_sql=\"$SQL_log\", event_notes='$audiofile_name $AF_path $AF_orig Invalid: $invalid_wav $wav_type "._QXZ("channels").": $wav_channels "._QXZ("framerate").": $wav_framerate "._QXZ("bits").": $wav_bits "._QXZ("compression").": $wav_compression "._QXZ("length").": $audio_length $affected_rowsX|$affected_rowsY';";
if ($DB) {echo "|$stmt|\n";}
$rslt=mysql_to_mysqli($stmt, $link);
}
diff --git a/www/vicidial/non_agent_api.php b/www/vicidial/non_agent_api.php
index ffb92035..ba659b75 100644
--- a/www/vicidial/non_agent_api.php
+++ b/www/vicidial/non_agent_api.php
@@ -168,10 +168,11 @@
# 210316-2207 - Added lead_all_info function
# 210319-1720 - Added special 'xDAYS' value option for callback_datetime
# 210320-2127 - Added 'custom_fields_add' option for update_list function
+# 210322-1218 - Added display of bad wav file formats on sounds_list function
#
-$version = '2.14-145';
-$build = '210320-2127';
+$version = '2.14-146';
+$build = '210322-1218';
$api_url_log = 0;
$startMS = microtime();
@@ -1202,6 +1203,18 @@ if ($function == 'sounds_list')
exit;
}
+ $bad_wavs='|';
+ $stmt="SELECT audio_filename from audio_store_details where wav_asterisk_valid='BAD';";
+ $rslt=mysql_to_mysqli($stmt, $link);
+ $bw_ct = mysqli_num_rows($rslt);
+ $bw=0;
+ while ($bw_ct > $bw)
+ {
+ $row=mysqli_fetch_row($rslt);
+ $bad_wavs .= "$row[0]|";
+ $bw++;
+ }
+
$dh = opendir($dirpath);
if ($DB>0) {echo "DEBUG: sounds_list variables - $dirpath|$stage|$format\n";}
@@ -1297,8 +1310,18 @@ if ($function == 'sounds_list')
echo "\n";
}
$sf++;
+ $BWB=''; $BWE='';
+ if ( (preg_match('/\.wav$/', $file_names[$m])) and (strlen($bad_wavs) > 2) )
+ {
+ $temp_filename = $file_names[$m];
+ if (preg_match("/\|$temp_filename\|/",$bad_wavs))
+ {
+ $BWB='';
+ $BWE=" "._QXZ("BAD WAV FORMAT")."";
+ }
+ }
echo "| $sf | \n";
- echo "$file_names[$m] | \n";
+ echo "$BWB$file_names[$m]$BWE | \n";
echo "$file_dates[$m] | \n";
echo "$file_sizes[$m] | \n";
echo ""._QXZ("PLAY")." |
\n";