CMU Sphinx with VoxForge has total failure to recognize words - why? - cmusphinx

I am trying to setup VoxForge 0.4 English acoustic model - as described in https://stackoverflow.com/a/8699337/519995 (but adapted to Raw configuration and not XML). When I switched to VoxForge my error rate went up to 100% !
I get results that do not resemble the input sounds at all.
I guess I configured something wrong, but I can't figure out what.
Below are the modifications I made (starting from RawHelloNGram.java demo).
When VOX_FORGE is false everything works decently, when it is true everything fails to recognize.
this.modelLoader = new Sphinx3Loader(
VOX_FORGE ?
"file:"+PROJECT_DIR+"/voxforge-en-0.4/model_parameters/voxforge_en_sphinx.cd_cont_5000"
: "resource:/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz",
"mdef",
"",
logMath,
unitManager,
0.0f,
1e-7f,
0.0001f,
true);
this.model = new TiedStateAcousticModel(modelLoader, unitManager, true);
// changed parameters of mel-Filter
this.melFilterBank = new MelFrequencyFilterBank(
VOX_FORGE ? 200.0 : 130.0, // minFreq,
VOX_FORGE ? 3500.0 : 6800.0, // maxFreq,
VOX_FORGE ? 31 : 40 // numberFilters
);
if (VOX_FORGE) {
this.featureTransform = new FeatureTransform(
modelLoader
);
}
...
... later at the end of the pipeline setup
if (VOX_FORGE) {
pipeline.add(featureTransform);
}
For completeness - this is the entire configuration I'm using: https://gist.github.com/Iftahh/7336283

Voxforge uses standard mel filterbank parameters (see feat.params).
-nfilt 40
-lowerf 133.333334
-upperf 6855.4976
There is no need to set melfilterbank to 200/3500/31

Related

PHPmailer parseAddresses - How to get rid of "notice" messages

I'm trying to get rid of the following message in one of my scripts when using the PHPmailer parseAddresses function:
Notice: Unknown: Must use comma to separate addresses: xxx (errflg=3) in Unknown on line 0
$mailer = new PHPMailer(true);
try {
$a = $mailer->parseAddresses('aaa#aaa.aaa xxx');
}
finally {
...
}
I'm using PHP 7.0.8 with the following error handling presets:
declare(strict_types = 1);
error_reporting(E_ALL);
ini_set('display_errors', 'stdout');
I know that I can just stop the errors from being displayed but this doesn't seem to be the proper way to do. And of course I know that the provided email addresses in my example are not correct...
I'm not sure what you're complaining about: it's telling you you have malformed input when you provide malformed input! The way to avoid the error is not to pass in malformed input!
As the error says, it's expecting one or more addresses in comma-delimited RFC822 format (not what you provided), which might be something like:
xxx <aaa#aaa.aaa>, yyy <bbb#aaa.aaa>
If you don't provide data in that format, it will complain, as you're seeing. This is covered in the docs on the parseAddress method.
Are you expecting it to do something else?
PHPMailer writes notices to output, so you could start an output buffer and just flush it after your call. Something like:
$mailer = new PHPMailer(true);
try {
ob_start();
$a = $mailer->parseAddresses('aaa#aaa.aaa xxx');
//$notices = ob_get_contents();
ob_end_clean();
}
finally {
...
}
I had to deal with the same issues. Simply created a homemade solution that does mostly the same thing in a more flexible way. For anyone that is interested:
/**
* split_addresses Split a list of email addresses with potential validation
* Similar concept as PHPMailer->parseAddresses, but more forgiving
* #param $list - a list of comma delimited email addresses in simple or RFC822 format
* #param $default_name an optional name to add if not present
* #param $validate logical var to indicate to only accept validated emails
* #author Jacques Amar
* #copyright 2019 Amar Micro Inc.
*/
function split_addresses($list, $default_name='', $validate=true) {
$valid_arr = [];
if (empty($list)) { return $valid_arr; }
$split_arr = preg_split('/\s*,\s*/', $list);
foreach ($split_arr as $email_candidate) {
// Validate email_candidate if the form "first last <adrs#email.com>"
$actual_name = $default_name;
$actual_email = $email_candidate;
if (preg_match('/\s*(.+)\s*\<\s*([^#]+#.+)\s*\>/', $email_candidate, $actual_emails) == 1) {
$actual_name = $actual_emails[1];
$actual_email = $actual_emails[2];
}
if ($validate) {
if (filter_var($actual_email, FILTER_VALIDATE_EMAIL)) {
$valid_arr[] = ['address' => $actual_email, 'name' => $actual_name];
}
} else {
$valid_arr[] = ['address' => $actual_email, 'name' => $actual_name];
}
}
return $valid_arr;
}
Should be self explanatory

Photoshop: How to handle numbering a large amount of disorganized items?

Suppose I have a large campsite like "seating" chart with several hundred lots sectioned off and outlined in photoshop. (each lot is roughly a square) Every lot needs to be numbered in photoshop and also editable in the future in case of changes. The lots are scattered and curve around the landscape so entering text in one layer seems out since for example lot 27 with be on the right and rotate 20 degrees to match the lot and yet lot 185 might be way over on the left at a far different angle.
Is there an elegant way to do this or at least quickly import a large number sequence that places one number per layer so I can grab them and orient them to their corresponding lot quickly instead of typing out and then positioning ever number individually? I'm having trouble thinking up an elegant/fast way to handle this in Photoshop...
Edit 1 - picture: http://i.imgur.com/UT3DRBi.jpg
You can do it with Extendscript. I am not the best of Extendscript programmers, but the following script will ask you for the number of text labels you want and add that many numbers on sepearate layers. Of course, you can diddle around with the font, colour, position, size etc. but it should get you started.
Here is an example - I turned off layers 4 and 5 so you can see each number is on a new layer.
Here it asks how many numbers you want:
// Setchell - AddNumbers - Adobe Photoshop Script
// Description: Asks user for number of numbers to add, each in own layer
// Version: 0.1
// Author: Mark Setchell (mark#thesetchells.com)
// Web: http://www.thesetchells.com
// ============================================================================
// Installation:
// 1. Place script in 'C:\Program Files\Adobe\Adobe Photoshop CS#\Presets\Scripts\'
// 2. Restart Photoshop
// 3. Choose File > Scripts > AddNumbers
// ============================================================================
// enable double-clicking from Mac Finder or Windows Explorer
// this command only works in Photoshop CS2 and higher
#target photoshop
// bring application forward for double-click events
app.bringToFront();
///////////////////////////////////////////////////////////////////////////////
// AddNumbers
///////////////////////////////////////////////////////////////////////////////
function AddNumbers() {
// Change Debug=1 for extra debugging messages
var Debug=1;
// Get user to enter common stem for JPEG names
var dialog = new Window('dialog', 'Setchell - AddNumbers');
dialog.size = {width:500, height:100};
dialog.stem = dialog.add('edittext',undefined, '<Enter ending number>');
dialog.stem.size = {width:400,height:25};
dialog.stem.value = true;
dialog.stem.buildBtn = dialog.add('button', undefined,'OK', {name:'ok'});
dialog.show();
// Pick up what user entered - just digits
var limit=dialog.stem.text.match(/\d+/);
// Debug
if(Debug)alert(limit);
var cnt;
var n=0;
var nPer=10;
var deltaX=app.activeDocument.width/nPer;
var deltaY=app.activeDocument.height/nPer;
var tX=0;
var tY=deltaY;
app.preferences.typeUnits = TypeUnits.POINTS;
for(cnt=1;cnt<=limit;cnt++){
// Adds a new layer to the active document and stores it in a variable named “myTextLayer”.
var myTextLayer = app.activeDocument.artLayers.add();
// Changes myTextLayer from normal to a text layer.
myTextLayer.kind = LayerKind.TEXT;
// Gets a reference to the textItem property of myTextLayer.
var myText = myTextLayer.textItem;
// sets the font size of the text to 16.
myText.size = 16;
// Sets the contents of the textItem.
myText.contents = cnt;
// Position the label - could be improved :-)
tX=n*deltaX;
myText.position = new Array(tX, tY);
n++;
if(n==nPer){
tY+=deltaY;
n=0;
}
}
return;
}
///////////////////////////////////////////////////////////////////////////////
// isCorrectVersion - check for Adobe Photoshop CS2 (v9) or higher
///////////////////////////////////////////////////////////////////////////////
function isCorrectVersion() {
if (parseInt(version, 10) >= 9) {
return true;
}
else {
alert('This script requires Adobe Photoshop CS2 or higher.', 'Wrong Version', false);
return false;
}
}
///////////////////////////////////////////////////////////////////////////////
// showError - display error message if something goes wrong
///////////////////////////////////////////////////////////////////////////////
function showError(err) {
if (confirm('An unknown error has occurred.\n' +
'Would you like to see more information?', true, 'Unknown Error')) {
alert(err + ': on line ' + err.line, 'Script Error', true);
}
}
// test initial conditions prior to running main function
if (isCorrectVersion()) {
// Save current RulerUnits to restore when we have finished
var savedRulerUnits = app.preferences.rulerUnits;
// Set RulerUnits to PIXELS
app.preferences.rulerUnits = Units.PIXELS;
try {
AddNumbers();
}
catch(e) {
// don't report error on user cancel
if (e.number != 8007) {
showError(e);
}
}
// Restore RulerUnits to whatever they were when we started
app.preferences.rulerUnits = savedRulerUnits;
}

How to specify different delays between slides in bxslider

Ran across the following problem in bxslider- how can you apply different delays between slides in the auto show?
I came up with the following solution which I will show here:
in the jquery.bxslider.js replace:
el.startAuto = function(preventControlUpdate){
// if an interval already exists, disregard call
if(slider.interval) return;
// create an interval
slider.interval = setInterval(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
}, slider.settings.pause);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
}
With
/**EDITS: By CRB - techdude **/
el.startAuto = function(preventControlUpdate){
el.continueAuto();
}
el.continueAuto = function(){
//get how long the current slide should stay
var duration = slider.children.eq(parseInt(slider.active.index)).attr("duration");
if(duration == ""){
duration = slider.settings.pause;
} else {
duration = parseInt(duration);
}
console.log(duration);
// create a timeout
slider.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
// if auto controls are displayed and preventControlUpdate is not true
if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
}
//*End Edits*/
Then to change the duration of a slide, simply give its li tag a duration attribute like this:
where duration is the number of milliseconds for the slide to pause.
To set the default duration, simply use the pause: option in the settings:
$("element").bxSlider({
auto:true,
pause: 4000
};
Hope this helps. Maybe bx slider will even add it to a future version. :)
What are the you're using to pick this up? Any way you can put up a gist of it working?
Perhaps this will help clarify:
In principle, the way this works is I change the setInterval with a setTimeout so the interval can be changed each time.
The key to getting multiple elements to work on a page is to not use the slider.timer object, but probably to use the el.timer object so the line would read something like,
el.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
Instead of
slider.timer = setTimeout(function(){
slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
el.continueAuto();
}, duration);
I haven't tested it with multiple sliders, but let me know if this works. That is the principle anyway. The only problem with this, however, is that I believe that you would need to modify the el.pause method to use the el.timer as well, otherwise the slideshow can't be paused. I think that was the reason I did it the way I did. However, it was a long time ago.

How to render block programmatically with standard theme

I know how to get block data by module_invoke(),
but how to use standard block theme for rendering it.
I tried to use theme() function but with no success.
Could somebody give me advice?
Regards
Taken from the API comments for theme_block
// setup vars
$module = 'system';
$delta = 0; // could also be a string
// renders the "Powered by Drupal" block
// #see hook_block()
// #see module_invoke()
$block = module_invoke($module, 'block', 'view', $delta);
// must be converted to an object
$block = !empty($block) ? (object)$block : new stdclass;
$block->module = $module;
$block->delta = $delta;
$block->region = 'whateverYouWant';
echo theme('block',$block);
Haven't tested it but it seems to be doing what you want. This uses the regular theme function to theme the block you are retrieving

How to export audio-media from a MOV-file with QuickTime-API?

I want to export the audio-media of a MOV-File with the QuickTime-API and save it to an WAV-File (or something equivalent). How can I do that? I use Windows XP.
Sorry if I am stating the obvious, but you should be able to achieve this the same way as described here:
Export every frame as image from a Movie-File (QuickTime-API)
Or do you need to do this in a non-interactive way?
Edit
To export the audio media of a Movie file to WAVE non-interactively using a Movie Exporter, use the following code:
"include "QuickTimeComponents.h"
...
// aquire Movie
...
ComponentDescription desc;
MovieExportComponent exporter;
char filename[255];
FSSpec fsspec;
int flags;
// first we have to find a Movie Exporter capable of eporting the format we want
desc.componentType = MovieExportType;
desc.componentSubType = kQTFileTypeWave; // 'WAVE'
desc.componentManufacturer = SoundMediaType;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
// and create an instance of it
exporter = OpenComponent( FindNextComponent( 0, &desc ) );
// then set up a FSSpec for our output file
sprintf( outfilename, "C:/test.wav" );
c2pstr( outfilename );
FSMakeFSSpec( 0, 0L, (ConstStr255Param)outfilename, &fsspec );
// if you do error handling take care to ignore fnfErr being returned
// by FSMakeFSSpec - we're about to create a new file after all
// then finally initiate the conversion
flags= createMovieFileDeleteCurFile | movieToFileOnlyExport;
ConvertMovieToFile( movie, 0, &fsspec, kQTFileTypeWave, 'TVOD', 0, 0, flags, exporter );
CloseComponent( exporter );
...
// Clean up
...
ffmpeg is easily capable of this and can be compiled under the LGPL if needed for commercial software. If you need more customizable hooks you can use libavcodec and libavformat from the same project.
with mplayer
mplayer.exe -ao pcm:file=output.wav -vo null -vc dummy input.mov

Resources