diff --git a/src/pocketsphinx/ad.pas b/src/pocketsphinx/ad.pas index 2b03ba7..4eca010 100644 --- a/src/pocketsphinx/ad.pas +++ b/src/pocketsphinx/ad.pas @@ -4,11 +4,14 @@ Copyright (c) 2017 Damian Woroch, http://r1me.pl } {$IFDEF FPC} -{$mode objfpc}{$H+} +{$mode delphi}{$H+} {$ENDIF} interface +uses + dynlibs; + const {$IFDEF Linux} sphinxadlib = 'libsphinxad.so.3'; @@ -41,43 +44,72 @@ ad_rec_s = record ad_rec_t = ad_rec_s; pad_rec_t = ^ad_rec_t; -{** - * Open a specific audio device for recording. - * - * The device is opened in non-blocking mode and placed in idle state. - * - * @return pointer to read-only ad_rec_t structure if successful, NULL - * otherwise. The return value to be used as the first argument to - * other recording functions. - *} -function ad_open_dev(const dev: PUTF8Char; samples_per_sec: Integer): pad_rec_t; cdecl; external sphinxadlib; - -{** - * Open the default audio device with a given sampling rate. - *} -function ad_open_sps(samples_per_sec: Integer): pad_rec_t; cdecl; external sphinxadlib; - -{** - * Open the default audio device. - *} -function ad_open: pad_rec_t; cdecl; external sphinxadlib; - -{* Start audio recording. Return value: 0 if successful, <0 otherwise *} -function ad_start_rec(rec: pad_rec_t): Integer; cdecl; external sphinxadlib; - -{* Stop audio recording. Return value: 0 if successful, <0 otherwise *} -function ad_stop_rec(rec: pad_rec_t): Integer; cdecl; external sphinxadlib; - -{* Close the recording device. Return value: 0 if successful, <0 otherwise *} -function ad_close(rec: pad_rec_t): Integer; cdecl; external sphinxadlib; - -{* - * Read next block of audio samples while recording; read upto max samples into buf. - * Return value: # samples actually read (could be 0 since non-blocking); -1 if not - * recording and no more samples remaining to be read from most recent recording. - *} -function ad_read(rec: pad_rec_t; buf: Pointer; max: Integer): Integer; cdecl; external sphinxadlib; +type + {** + * Open a specific audio device for recording. + * + * The device is opened in non-blocking mode and placed in idle state. + * + * @return pointer to read-only ad_rec_t structure if successful, NULL + * otherwise. The return value to be used as the first argument to + * other recording functions. + *} + Tad_open_dev = function (const dev: PUTF8Char; samples_per_sec: Integer): pad_rec_t; cdecl; + + {** + * Open the default audio device with a given sampling rate. + *} + Tad_open_sps = function (samples_per_sec: Integer): pad_rec_t; cdecl; + + {** + * Open the default audio device. + *} + Tad_open = function : pad_rec_t; cdecl; + + {* Start audio recording. Return value: 0 if successful, <0 otherwise *} + Tad_start_rec = function (rec: pad_rec_t): Integer; cdecl; + + {* Stop audio recording. Return value: 0 if successful, <0 otherwise *} + Tad_stop_rec = function (rec: pad_rec_t): Integer; cdecl; + + {* Close the recording device. Return value: 0 if successful, <0 otherwise *} + Tad_close = function(rec: pad_rec_t): Integer; cdecl; + + {* + * Read next block of audio samples while recording; read upto max samples into buf. + * Return value: # samples actually read (could be 0 since non-blocking); -1 if not + * recording and no more samples remaining to be read from most recent recording. + *} + Tad_read = function (rec: pad_rec_t; buf: Pointer; max: Integer): Integer; cdecl; + +var + Lib: TLibHandle; + ad_open_dev: Tad_open_dev; + ad_open_sps: Tad_open_sps; + ad_open: Tad_open; + ad_start_rec: Tad_start_rec; + ad_stop_rec: Tad_stop_rec; + ad_close: Tad_close; + ad_read: Tad_read; implementation +procedure LoadLibrary; +begin + Lib := DynLibs.LoadLibrary(sphinxadlib); + if Lib <> DynLibs.NilHandle then + begin + ad_open_dev := GetProcAddress(Lib, 'ad_open_dev'); + ad_open_sps := GetProcAddress(Lib, 'ad_open_sps'); + ad_open := GetProcAddress(Lib, 'ad_open'); + ad_start_rec := GetProcAddress(Lib, 'ad_start_rec'); + ad_stop_rec := GetProcAddress(Lib, 'ad_stop_rec'); + ad_close := GetProcAddress(Lib, 'ad_close'); + ad_read := GetProcAddress(Lib, 'ad_read'); + end; +end; + +initialization + LoadLibrary; + end. diff --git a/src/pocketsphinx/cmd_ln.pas b/src/pocketsphinx/cmd_ln.pas index 2f0e625..4a8ada8 100644 --- a/src/pocketsphinx/cmd_ln.pas +++ b/src/pocketsphinx/cmd_ln.pas @@ -4,11 +4,14 @@ Copyright (c) 2017 Damian Woroch, http://r1me.pl } {$IFDEF FPC} -{$mode objfpc}{$H+} +{$mode delphi}{$H+} {$ENDIF} interface +uses + dynlibs; + const {$IFDEF Linux} sphinxbaselib = 'libsphinxbase.so.3'; @@ -39,16 +42,34 @@ interface * @param strict Whether to fail on duplicate or unknown arguments. * @return A cmd_ln_t* containing the results of command line parsing, or NULL on failure. *} -function cmd_ln_init(inout_cmdln: pcmd_ln_t; defn: parg_t; bfailunk: Boolean): pcmd_ln_t; cdecl; varargs external sphinxbaselib; + Tcmd_ln_init = function(inout_cmdln: pcmd_ln_t; defn: parg_t; bfailunk: Boolean): pcmd_ln_t; cdecl varargs; {** * Release a command-line argument set and all associated strings. * * @return new reference count (0 if freed completely) *} -function cmd_ln_free_r(cmdln: pcmd_ln_t): Integer; cdecl; external sphinxbaselib; + Tcmd_ln_free_r = function(cmdln: pcmd_ln_t): Integer; cdecl; + +var + Lib: TLibHandle; + cmd_ln_init: Tcmd_ln_init; + cmd_ln_free_r: Tcmd_ln_free_r; implementation +procedure LoadLibrary; +begin + Lib := DynLibs.LoadLibrary(sphinxbaselib); + if Lib <> DynLibs.NilHandle then + begin + cmd_ln_init := GetProcAddress(Lib, 'cmd_ln_init'); + cmd_ln_free_r := GetProcAddress(Lib, 'cmd_ln_free_r'); + end; +end; + +initialization + LoadLibrary; + end. diff --git a/src/pocketsphinx/pocketsphinx.pas b/src/pocketsphinx/pocketsphinx.pas index a0580db..768d389 100644 --- a/src/pocketsphinx/pocketsphinx.pas +++ b/src/pocketsphinx/pocketsphinx.pas @@ -4,12 +4,12 @@ Copyright (c) 2017 Damian Woroch, http://r1me.pl } {$IFDEF FPC} -{$mode objfpc}{$H+} +{$mode delphi}{$H+} {$ENDIF} interface uses - cmd_ln; + cmd_ln, dynlibs; const {$IFDEF Linux} @@ -41,7 +41,7 @@ interface * Sets default grammar and language model if they are not set explicitly and * are present in the default search path. *} -procedure ps_default_search_args(pcmd_ln_t: pcmd_ln_t); cdecl; external pocketsphinxlib; + Tps_default_search_args = procedure (pcmd_ln_t: pcmd_ln_t); cdecl; {** * Initialize the decoder from a configuration object. @@ -53,7 +53,7 @@ procedure ps_default_search_args(pcmd_ln_t: pcmd_ln_t); cdecl; external pocketsp * @param config a command-line structure, as created by * cmd_ln_parse_r() or cmd_ln_parse_file_r(). *} -function ps_init(config: pcmd_ln_t): pps_decoder_t; cdecl; external pocketsphinxlib; + Tps_init = function (config: pcmd_ln_t): pps_decoder_t; cdecl; {** * Reinitialize the decoder with updated configuration. @@ -72,7 +72,7 @@ function ps_init(config: pcmd_ln_t): pps_decoder_t; cdecl; external pocketsphinx * with any changes applied. * @return 0 for success, <0 for failure. *} -function ps_reinit(ps: pps_decoder_t; config: pcmd_ln_t): Integer; cdecl; external pocketsphinxlib; + Tps_reinit = function (ps: pps_decoder_t; config: pcmd_ln_t): Integer; cdecl; {** * Returns the argument definitions used in ps_init(). @@ -80,7 +80,7 @@ function ps_reinit(ps: pps_decoder_t; config: pcmd_ln_t): Integer; cdecl; extern * This is here to avoid exporting global data, which is problematic * on Win32 and Symbian (and possibly other platforms). *} -function ps_args: parg_t; cdecl external pocketsphinxlib; + Tps_args = function : parg_t; cdecl; {** * Retain a pointer to the decoder. @@ -92,7 +92,7 @@ function ps_args: parg_t; cdecl external pocketsphinxlib; * * @return pointer to retained decoder. *} -function ps_retain(ps: pps_decoder_t): pps_decoder_t; cdecl; external pocketsphinxlib; + Tps_retain = function (ps: pps_decoder_t): pps_decoder_t; cdecl; {** * Finalize the decoder. @@ -104,7 +104,7 @@ function ps_retain(ps: pps_decoder_t): pps_decoder_t; cdecl; external pocketsphi * @param ps Decoder to be freed. * @return New reference count (0 if freed). *} -function ps_free(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; + Tps_free = function (ps: pps_decoder_t): Integer; cdecl; {** * Get the configuration object for this decoder. @@ -114,7 +114,7 @@ function ps_free(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; * attempt to free it manually. Use cmd_ln_retain() if you * wish to reuse it elsewhere. *} -function ps_get_config(ps: pps_decoder_t): pcmd_ln_t; cdecl; external pocketsphinxlib; + Tps_get_config = function (ps: pps_decoder_t): pcmd_ln_t; cdecl; {** * Get the log-math computation object for this decoder. @@ -124,7 +124,7 @@ function ps_get_config(ps: pps_decoder_t): pcmd_ln_t; cdecl; external pocketsphi * free it manually. Use logmath_retain() if you wish to * reuse it elsewhere. *} -function ps_get_logmath(ps: pps_decoder_t): plogmath_t; cdecl external pocketsphinxlib; + Tps_get_logmath = function (ps: pps_decoder_t): plogmath_t; cdecl; {** * Get the feature extraction object for this decoder. @@ -134,7 +134,7 @@ function ps_get_logmath(ps: pps_decoder_t): plogmath_t; cdecl external pocketsph * not attempt to free it manually. Use fe_retain() if you * wish to reuse it elsewhere. *} -function ps_get_fe(ps: pps_decoder_t): pfe_t; cdecl external pocketsphinxlib; + Tps_get_fe = function (ps: pps_decoder_t): pfe_t; cdecl; {** * Get the dynamic feature computation object for this decoder. @@ -144,7 +144,7 @@ function ps_get_fe(ps: pps_decoder_t): pfe_t; cdecl external pocketsphinxlib; * not attempt to free it manually. Use feat_retain() if you * wish to reuse it elsewhere. *} -function ps_get_feat(ps: pps_decoder_t): pfeat_t; cdecl external pocketsphinxlib; + Tps_get_feat = function (ps: pps_decoder_t): pfeat_t; cdecl; {** * Adapt current acoustic model using a linear transform. @@ -157,7 +157,7 @@ function ps_get_feat(ps: pps_decoder_t): pfeat_t; cdecl external pocketsphinxlib * @return The updated transform object for this decoder, or * NULL on failure. *} -function ps_update_mllr(ps: pps_decoder_t; mllr: pps_mllr_t): pps_mllr_t; cdecl external pocketsphinxlib; + Tps_update_mllr = function (ps: pps_decoder_t; mllr: pps_mllr_t): pps_mllr_t; cdecl; {** * Reload the pronunciation dictionary from a file. @@ -173,8 +173,8 @@ function ps_update_mllr(ps: pps_decoder_t; mllr: pps_mllr_t): pps_mllr_t; cdecl * @param format Format of the dictionary file, or NULL to determine * automatically (currently unused,should be NULL) *} -function ps_load_dict(ps: pps_decoder_t; - const dictfile, fdictfile, format: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_load_dict = function (ps: pps_decoder_t; + const dictfile, fdictfile, format: PUTF8Char): Integer; cdecl; {** * Dump the current pronunciation dictionary to a file. @@ -185,8 +185,8 @@ function ps_load_dict(ps: pps_decoder_t; * @param format Format of the dictionary file, or NULL for the * default (text) format (currently unused, should be NULL) *} -function ps_save_dict(ps: pps_decoder_t; - const dictfile, format: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_save_dict = function (ps: pps_decoder_t; + const dictfile, format: PUTF8Char): Integer; cdecl; {** * Add a word to the pronunciation dictionary. @@ -207,9 +207,9 @@ function ps_save_dict(ps: pps_decoder_t; * @return The internal ID (>= 0) of the newly added word, or <0 on * failure. *} -function ps_add_word(ps: pps_decoder_t; + Tps_add_word = function (ps: pps_decoder_t; const word, phones: PUTF8Char; - update: Integer): Integer; cdecl; external pocketsphinxlib; + update: Integer): Integer; cdecl; {** * Lookup for the word in the dictionary and return phone transcription @@ -222,7 +222,7 @@ function ps_add_word(ps: pps_decoder_t; * or NULL if word is not present in the dictionary. The string is * allocated and must be freed by the user. *} -function ps_lookup_word(ps: pps_decoder_t; const word: PUTF8Char): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_lookup_word = function (ps: pps_decoder_t; const word: PUTF8Char): PUTF8Char; cdecl; {** * Decode a raw audio stream. @@ -238,7 +238,7 @@ function ps_lookup_word(ps: pps_decoder_t; const word: PUTF8Char): PUTF8Char; cd * to read until end-of-file. * @return Number of samples of audio. *} -function ps_decode_raw(ps: pps_decoder_t; rawfh: Cardinal; maxsamps: Integer): Integer; cdecl; external pocketsphinxlib; + Tps_decode_raw = function (ps: pps_decoder_t; rawfh: Cardinal; maxsamps: Integer): Integer; cdecl; {** * Decode a senone score dump file. @@ -247,7 +247,7 @@ function ps_decode_raw(ps: pps_decoder_t; rawfh: Cardinal; maxsamps: Integer): I * @param fh Previously opened file handle positioned at start of file. * @return Number of frames read. *} -function ps_decode_senscr(ps: pps_decoder_t; senfh: THandle): Integer; cdecl external pocketsphinxlib; + Tps_decode_senscr = function (ps: pps_decoder_t; senfh: THandle): Integer; cdecl; {** * Start processing of the stream of speech. Channel parameters like @@ -256,7 +256,7 @@ function ps_decode_senscr(ps: pps_decoder_t; senfh: THandle): Integer; cdecl ext * * @return 0 for success, <0 on error. *} -function ps_start_stream(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; + Tps_start_stream = function (ps: pps_decoder_t): Integer; cdecl; {** * Start utterance processing. @@ -268,7 +268,7 @@ function ps_start_stream(ps: pps_decoder_t): Integer; cdecl; external pocketsphi * @param ps Decoder to be started. * @return 0 for success, <0 on error. *} -function ps_start_utt(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; + Tps_start_utt = function (ps: pps_decoder_t): Integer; cdecl; {** * Decode raw audio data. @@ -283,11 +283,11 @@ function ps_start_utt(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxl * produce more accurate results. * @return Number of frames of data searched, or <0 for error. *} -function ps_process_raw(ps: pps_decoder_t; + Tps_process_raw = function (ps: pps_decoder_t; const data: Pointer; n_samples: NativeInt; no_search: LongBool; - full_utt: LongBool): Integer; cdecl; external pocketsphinxlib; + full_utt: LongBool): Integer; cdecl; {** * Decode acoustic feature data. @@ -302,11 +302,11 @@ function ps_process_raw(ps: pps_decoder_t; * produce more accurate results. * @return Number of frames of data searched, or <0 for error. *} -function ps_process_cep(ps: pps_decoder_t; + Tps_process_cep = function (ps: pps_decoder_t; data: pmfcc_t; n_frames: Integer; no_search: Integer; - full_utt: Integer): Integer; cdecl external pocketsphinxlib; + full_utt: Integer): Integer; cdecl; {** * Get the number of frames of data searched. @@ -321,7 +321,7 @@ function ps_process_cep(ps: pps_decoder_t; * @return Number of frames of speech data which have been recognized * so far. *} -function ps_get_n_frames(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; + Tps_get_n_frames = function (ps: pps_decoder_t): Integer; cdecl; {** * End utterance processing. @@ -329,7 +329,7 @@ function ps_get_n_frames(ps: pps_decoder_t): Integer; cdecl; external pocketsphi * @param ps Decoder. * @return 0 for success, <0 on error *} -function ps_end_utt(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib; + Tps_end_utt = function (ps: pps_decoder_t): Integer; cdecl; {** * Get hypothesis string and path score. @@ -339,7 +339,7 @@ function ps_end_utt(ps: pps_decoder_t): Integer; cdecl; external pocketsphinxlib * @return String containing best hypothesis at this point in * decoding. NULL if no hypothesis is available. *} -function ps_get_hyp(ps: pps_decoder_t; out out_best_score: Integer): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_get_hyp = function (ps: pps_decoder_t; out out_best_score: Integer): PUTF8Char; cdecl; {** * Get hypothesis string and final flag. @@ -349,7 +349,7 @@ function ps_get_hyp(ps: pps_decoder_t; out out_best_score: Integer): PUTF8Char; * @return String containing best hypothesis at this point in * decoding. NULL if no hypothesis is available. *} -function ps_get_hyp_final(ps: pps_decoder_t; out out_is_final: Integer): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_get_hyp_final = function (ps: pps_decoder_t; out out_is_final: Integer): PUTF8Char; cdecl; {** * Get posterior probability. @@ -364,7 +364,7 @@ function ps_get_hyp_final(ps: pps_decoder_t; out out_is_final: Integer): PUTF8Ch * @param ps Decoder. * @return Posterior probability of the best hypothesis. *} -function ps_get_prob(ps: pps_decoder_t): Integer; cdecl external pocketsphinxlib; + Tps_get_prob = function (ps: pps_decoder_t): Integer; cdecl; {** * Get word lattice. @@ -379,7 +379,7 @@ function ps_get_prob(ps: pps_decoder_t): Integer; cdecl external pocketsphinxlib * It is only valid until the next utterance, unless you use * ps_lattice_retain() to retain it. *} -function ps_get_lattice(ps: pps_decoder_t): pps_lattice_t; cdecl external pocketsphinxlib; + Tps_get_lattice = function (ps: pps_decoder_t): pps_lattice_t; cdecl; {** * Get an iterator over the word segmentation for the best hypothesis. @@ -388,7 +388,7 @@ function ps_get_lattice(ps: pps_decoder_t): pps_lattice_t; cdecl external pocket * @return Iterator over the best hypothesis at this point in * decoding. NULL if no hypothesis is available. *} -function ps_seg_iter(ps: pps_decoder_t): pps_seg_t; cdecl external pocketsphinxlib; + Tps_seg_iter = function (ps: pps_decoder_t): pps_seg_t; cdecl; {** * Get the next segment in a word segmentation. @@ -397,7 +397,7 @@ function ps_seg_iter(ps: pps_decoder_t): pps_seg_t; cdecl external pocketsphinxl * @return Updated iterator with the next segment. NULL at end of * utterance (the iterator will be freed in this case). *} -function ps_seg_next(seg: pps_seg_t): pps_seg_t; cdecl external pocketsphinxlib; + Tps_seg_next = function (seg: pps_seg_t): pps_seg_t; cdecl; {** * Get word string from a segmentation iterator. @@ -406,7 +406,7 @@ function ps_seg_next(seg: pps_seg_t): pps_seg_t; cdecl external pocketsphinxlib; * @return Read-only string giving string name of this segment. This * is only valid until the next call to ps_seg_next(). *} -function ps_seg_word(seg: pps_seg_t): PUTF8Char; cdecl external pocketsphinxlib; + Tps_seg_word = function (seg: pps_seg_t): PUTF8Char; cdecl; {** * Get inclusive start and end frames from a segmentation iterator. @@ -419,7 +419,7 @@ function ps_seg_word(seg: pps_seg_t): PUTF8Char; cdecl external pocketsphinxlib; * @param out_sf Output: First frame index in segment. * @param out_sf Output: Last frame index in segment. *} -procedure ps_seg_frames(seg: pps_seg_t; var out_sf: Integer; var out_ef: Integer); cdecl external pocketsphinxlib; + Tps_seg_frames = procedure (seg: pps_seg_t; var out_sf: Integer; var out_ef: Integer); cdecl; {** * Get language, acoustic, and posterior probabilities from a @@ -443,15 +443,15 @@ procedure ps_seg_frames(seg: pps_seg_t; var out_sf: Integer; var out_ef: Integer * to linear floating-point, use logmath_exp(ps_get_logmath(), * pprob). *} -function ps_seg_prob(seg: pps_seg_t; + Tps_seg_prob = function (seg: pps_seg_t; var out_ascr: Integer; var out_lscr: Integer; - var out_lback: Integer): Integer; cdecl external pocketsphinxlib; + var out_lback: Integer): Integer; cdecl; {** * Finish iterating over a word segmentation early, freeing resources. *} -procedure ps_seg_free(seg: pps_seg_t); cdecl external pocketsphinxlib; + Tps_seg_free = procedure (seg: pps_seg_t); cdecl; {** * Get an iterator over the best hypotheses. The function may also @@ -461,7 +461,7 @@ procedure ps_seg_free(seg: pps_seg_t); cdecl external pocketsphinxlib; * @param ps Decoder. * @return Iterator over N-best hypotheses or NULL if no hypothesis is available *} -function ps_nbest(ps: pps_decoder_t): pps_nbest_t; cdecl external pocketsphinxlib; + Tps_nbest = function (ps: pps_decoder_t): pps_nbest_t; cdecl; {** * Move an N-best list iterator forward. @@ -470,7 +470,7 @@ function ps_nbest(ps: pps_decoder_t): pps_nbest_t; cdecl external pocketsphinxli * @return Updated N-best iterator, or NULL if no more hypotheses are * available (iterator is freed ni this case). *} -function ps_nbest_next(nbest: pps_nbest_t): pps_nbest_t; cdecl external pocketsphinxlib; + Tps_nbest_next = function (nbest: pps_nbest_t): pps_nbest_t; cdecl; {** * Get the hypothesis string from an N-best list iterator. @@ -479,7 +479,7 @@ function ps_nbest_next(nbest: pps_nbest_t): pps_nbest_t; cdecl external pocketsp * @param out_score Output: Path score for this hypothesis. * @return String containing next best hypothesis. *} -function ps_nbest_hyp(nbest: pps_nbest_t; var out_score: Integer): PUTF8Char; cdecl external pocketsphinxlib; + Tps_nbest_hyp = function (nbest: pps_nbest_t; var out_score: Integer): PUTF8Char; cdecl; {** * Get the word segmentation from an N-best list iterator. @@ -488,14 +488,14 @@ function ps_nbest_hyp(nbest: pps_nbest_t; var out_score: Integer): PUTF8Char; cd * @param out_score Output: Path score for this hypothesis. * @return Iterator over the next best hypothesis. *} -function ps_nbest_seg(nbest: pps_nbest_t): pps_seg_t; cdecl external pocketsphinxlib; + Tps_nbest_seg = function (nbest: pps_nbest_t): pps_seg_t; cdecl; {** * Finish N-best search early, releasing resources. * * @param nbest N-best iterator. *} -procedure ps_nbest_free(nbest: pps_nbest_t); cdecl external pocketsphinxlib; + Tps_nbest_free = procedure (nbest: pps_nbest_t); cdecl; {** * Get performance information for the current utterance. @@ -505,10 +505,10 @@ procedure ps_nbest_free(nbest: pps_nbest_t); cdecl external pocketsphinxlib; * @param out_ncpu Output: Number of seconds of CPU time used. * @param out_nwall Output: Number of seconds of wall time used. *} -procedure ps_get_utt_time(ps: pps_decoder_t; + Tps_get_utt_time = procedure (ps: pps_decoder_t; var out_nspeech: double; var out_ncpu: double; - var out_nwall: double); cdecl external pocketsphinxlib; + var out_nwall: double); cdecl; {** * Get overall performance information. @@ -518,10 +518,10 @@ procedure ps_get_utt_time(ps: pps_decoder_t; * @param out_ncpu Output: Number of seconds of CPU time used. * @param out_nwall Output: Number of seconds of wall time used. *} -procedure ps_get_all_time(ps: pps_decoder_t; + Tps_get_all_time = procedure (ps: pps_decoder_t; var out_nspeech: double; var out_ncpu: double; - var out_nwall: double); cdecl external pocketsphinxlib; + var out_nwall: double); cdecl; {** * Checks if the last feed audio buffer contained speech @@ -529,7 +529,7 @@ procedure ps_get_all_time(ps: pps_decoder_t; * @param ps Decoder. * @return 1 if last buffer contained speech, 0 - otherwise *} -function ps_get_in_speech(ps: pps_decoder_t): ByteBool; cdecl external pocketsphinxlib; + Tps_get_in_speech = function (ps: pps_decoder_t): ByteBool; cdecl; {** * Sets the limit of the raw audio data to store in decoder @@ -538,7 +538,7 @@ function ps_get_in_speech(ps: pps_decoder_t): ByteBool; cdecl external pocketsph * @param ps Decoder * @param size bytes of the utterance to store *} -procedure ps_set_rawdata_size(ps: pps_decoder_t; size: Integer); cdecl external pocketsphinxlib; + Tps_set_rawdata_size = procedure (ps: pps_decoder_t; size: Integer); cdecl; {** * Retrieves the raw data collected during utterance decoding. @@ -548,8 +548,108 @@ procedure ps_set_rawdata_size(ps: pps_decoder_t; size: Integer); cdecl external * set before * @param size size of the data collected in samples (not bytes). *} -procedure ps_get_rawdata(ps: pps_decoder_t; buffer: Pointer; var size: Integer); cdecl external pocketsphinxlib; + Tps_get_rawdata = procedure (ps: pps_decoder_t; buffer: Pointer; var size: Integer); cdecl; + +var + Lib: TLibHandle; + ps_default_search_args: Tps_default_search_args; + ps_init: Tps_init; + ps_reinit: Tps_reinit; + ps_args: Tps_args; + ps_retain: Tps_retain; + ps_free: Tps_free; + ps_get_config: Tps_get_config; + ps_get_logmath: Tps_get_logmath; + ps_get_fe: Tps_get_fe; + ps_get_feat: Tps_get_feat; + ps_update_mllr: Tps_update_mllr; + ps_load_dict: Tps_load_dict; + ps_save_dict: Tps_save_dict; + ps_add_word: Tps_add_word; + ps_lookup_word: Tps_lookup_word; + ps_decode_raw: Tps_decode_raw; + ps_decode_senscr: Tps_decode_senscr; + ps_start_stream: Tps_start_stream; + ps_start_utt: Tps_start_utt; + ps_process_raw: Tps_process_raw; + ps_process_cep: Tps_process_cep; + ps_get_n_frames: Tps_get_n_frames; + ps_end_utt: Tps_end_utt; + ps_get_hyp: Tps_get_hyp; + ps_get_hyp_final: Tps_get_hyp_final; + ps_get_prob: Tps_get_prob; + ps_get_lattice: Tps_get_lattice; + ps_seg_iter: Tps_seg_iter; + ps_seg_next: Tps_seg_next; + ps_seg_word: Tps_seg_word; + ps_seg_frames: Tps_seg_frames; + ps_seg_prob: Tps_seg_prob; + ps_seg_free: Tps_seg_free; + ps_nbest: Tps_nbest; + ps_nbest_next: Tps_nbest_next; + ps_nbest_hyp: Tps_nbest_hyp; + ps_nbest_seg: Tps_nbest_seg; + ps_nbest_free: Tps_nbest_free; + ps_get_utt_time: Tps_get_utt_time; + ps_get_all_time: Tps_get_all_time; + ps_get_in_speech: Tps_get_in_speech; + ps_set_rawdata_size: Tps_set_rawdata_size; + ps_get_rawdata: Tps_get_rawdata; implementation +procedure LoadLibrary; +begin + Lib := DynLibs.LoadLibrary(pocketsphinxlib); + if Lib <> DynLibs.NilHandle then + begin + ps_default_search_args := GetProcAddress(Lib, 'ps_default_search_args'); + ps_init := GetProcAddress(Lib, 'ps_init'); + ps_reinit := GetProcAddress(Lib, 'ps_reinit'); + ps_args := GetProcAddress(Lib, 'ps_args'); + ps_retain := GetProcAddress(Lib, 'ps_retain'); + ps_free := GetProcAddress(Lib, 'ps_free'); + ps_get_config := GetProcAddress(Lib, 'ps_get_config'); + ps_get_logmath := GetProcAddress(Lib, 'ps_get_logmath'); + ps_get_fe := GetProcAddress(Lib, 'ps_get_fe'); + ps_get_feat := GetProcAddress(Lib, 'ps_get_feat'); + ps_update_mllr := GetProcAddress(Lib, 'ps_update_mllr'); + ps_load_dict := GetProcAddress(Lib, 'ps_load_dict'); + ps_save_dict := GetProcAddress(Lib, 'ps_save_dict'); + ps_add_word := GetProcAddress(Lib, 'ps_add_word'); + ps_lookup_word := GetProcAddress(Lib, 'ps_lookup_word'); + ps_decode_raw := GetProcAddress(Lib, 'ps_decode_raw'); + ps_decode_senscr := GetProcAddress(Lib, 'ps_decode_senscr'); + ps_start_stream := GetProcAddress(Lib, 'ps_start_stream'); + ps_start_utt := GetProcAddress(Lib, 'ps_start_utt'); + ps_process_raw := GetProcAddress(Lib, 'ps_process_raw'); + ps_process_cep := GetProcAddress(Lib, 'ps_process_cep'); + ps_get_n_frames := GetProcAddress(Lib, 'ps_get_n_frames'); + ps_end_utt := GetProcAddress(Lib, 'ps_end_utt'); + ps_get_hyp := GetProcAddress(Lib, 'ps_get_hyp'); + ps_get_hyp_final := GetProcAddress(Lib, 'ps_get_hyp_final'); + ps_get_prob := GetProcAddress(Lib, 'ps_get_prob'); + ps_get_lattice := GetProcAddress(Lib, 'ps_get_lattice'); + ps_seg_iter := GetProcAddress(Lib, 'ps_seg_iter'); + ps_seg_next := GetProcAddress(Lib, 'ps_seg_next'); + ps_seg_word := GetProcAddress(Lib, 'ps_seg_word'); + ps_seg_frames := GetProcAddress(Lib, 'ps_seg_frames'); + ps_seg_prob := GetProcAddress(Lib, 'ps_seg_prob'); + ps_seg_free := GetProcAddress(Lib, 'ps_seg_free'); + ps_nbest := GetProcAddress(Lib, 'ps_nbest'); + ps_nbest_next := GetProcAddress(Lib, 'ps_nbest_next'); + ps_nbest_hyp := GetProcAddress(Lib, 'ps_nbest_hyp'); + ps_nbest_seg := GetProcAddress(Lib, 'ps_nbest_seg'); + ps_nbest_free := GetProcAddress(Lib, 'ps_nbest_free'); + ps_get_utt_time := GetProcAddress(Lib, 'ps_get_utt_time'); + ps_get_all_time := GetProcAddress(Lib, 'ps_get_all_time'); + ps_get_in_speech := GetProcAddress(Lib, 'ps_get_in_speech'); + ps_set_rawdata_size := GetProcAddress(Lib, 'ps_set_rawdata_size'); + ps_get_rawdata := GetProcAddress(Lib, 'ps_get_rawdata'); + end; +end; + +initialization + LoadLibrary; + end. diff --git a/src/pocketsphinx/ps_search.pas b/src/pocketsphinx/ps_search.pas index 0938aac..3bd2a4c 100644 --- a/src/pocketsphinx/ps_search.pas +++ b/src/pocketsphinx/ps_search.pas @@ -4,12 +4,12 @@ Copyright (c) 2017 Damian Woroch, http://r1me.pl } {$IFDEF FPC} -{$mode objfpc}{$H+} +{$mode delphi}{$H+} {$ENDIF} interface uses - pocketsphinx; + pocketsphinx, dynlibs; type pps_search_iter_t = Pointer; @@ -24,14 +24,14 @@ interface * * @return 0 on success, -1 on failure *} -function ps_set_search(ps: pps_decoder_t; name: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_search = function(ps: pps_decoder_t; name: PUTF8Char): Integer; cdecl; {** * Returns name of curent search in decoder * * @see ps_set_search *} -function ps_get_search(ps: pps_decoder_t): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_get_search = function(ps: pps_decoder_t): PUTF8Char; cdecl; {** * Unsets the search and releases related resources. @@ -43,14 +43,14 @@ function ps_get_search(ps: pps_decoder_t): PUTF8Char; cdecl; external pocketsphi * @see ps_set_lm * @see ps_set_kws *} -function ps_unset_search(ps: pps_decoder_t; name: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_unset_search = function (ps: pps_decoder_t; name: PUTF8Char): Integer; cdecl; {** * Returns iterator over current searches * * @see ps_set_search *} -function ps_search_iter(ps: pps_decoder_t): pps_search_iter_t; cdecl; external pocketsphinxlib; + Tps_search_iter = function (ps: pps_decoder_t): pps_search_iter_t; cdecl; {** * Updates search iterator to point to the next position. @@ -59,21 +59,21 @@ function ps_search_iter(ps: pps_decoder_t): pps_search_iter_t; cdecl; external p * the final entry. * @see ps_set_search *} -function ps_search_iter_next(itor: pps_search_iter_t): pps_search_iter_t; cdecl; external pocketsphinxlib; + Tps_search_iter_next = function (itor: pps_search_iter_t): pps_search_iter_t; cdecl; {** * Retrieves the name of the search the iterator points to. * * @see ps_set_search *} -function ps_search_iter_val(itor: pps_search_iter_t): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_search_iter_val = function (itor: pps_search_iter_t): PUTF8Char; cdecl; {** * Delete an unfinished search iterator * * @see ps_set_search *} -procedure ps_search_iter_free(itor: pps_search_iter_t); cdecl; external pocketsphinxlib; + Tps_search_iter_free = procedure (itor: pps_search_iter_t); cdecl; {** * Get the language model set object for this decoder. @@ -86,7 +86,7 @@ procedure ps_search_iter_free(itor: pps_search_iter_t); cdecl; external pocketsp * not attempt to free it manually. Use ngram_model_retain() * if you wish to reuse it elsewhere. *} -function ps_get_lm(ps: pps_decoder_t; name: PUTF8Char): pngram_model_t; cdecl; external pocketsphinxlib; + Tps_get_lm = function (ps: pps_decoder_t; name: PUTF8Char): pngram_model_t; cdecl; {** * Adds new search based on N-gram language model. @@ -96,7 +96,7 @@ function ps_get_lm(ps: pps_decoder_t; name: PUTF8Char): pngram_model_t; cdecl; e * * @see ps_set_search. *} -function ps_set_lm(ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t): Integer; cdecl; external pocketsphinxlib; + Tps_set_lm = function (ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t): Integer; cdecl; {** * Adds new search based on N-gram language model. @@ -105,7 +105,7 @@ function ps_set_lm(ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t): Inte * * @see ps_set_lm *} -function ps_set_lm_file(ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_lm_file = function (ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; {** * Get the finite-state grammar set object for this decoder. @@ -116,7 +116,7 @@ function ps_set_lm_file(ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): In * @return The current FSG set object for this decoder, or * NULL if none is available. *} -function ps_get_fsg(ps: pps_decoder_t; name: PUTF8Char): pfsg_model_t; cdecl; external pocketsphinxlib; + Tps_get_fsg = function (ps: pps_decoder_t; name: PUTF8Char): pfsg_model_t; cdecl; {** * Adds new search based on finite state grammar. @@ -126,7 +126,7 @@ function ps_get_fsg(ps: pps_decoder_t; name: PUTF8Char): pfsg_model_t; cdecl; ex * * @see ps_set_search *} -function ps_set_fsg(ps: pps_decoder_t; name: PUTF8Char; fsg: pfsg_model_t): Integer; cdecl; external pocketsphinxlib; + Tps_set_fsg = function (ps: pps_decoder_t; name: PUTF8Char; fsg: pfsg_model_t): Integer; cdecl; {** * Adds new search using JSGF model. @@ -135,7 +135,7 @@ function ps_set_fsg(ps: pps_decoder_t; name: PUTF8Char; fsg: pfsg_model_t): Inte * * @see ps_set_fsg *} -function ps_set_jsgf_file(ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_jsgf_file = function (ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; {** * Adds new search using JSGF model. @@ -144,7 +144,7 @@ function ps_set_jsgf_file(ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): * * @see ps_set_fsg *} -function ps_set_jsgf_string(ps: pps_decoder_t; name: PUTF8Char; jsgf_string: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_jsgf_string = function (ps: pps_decoder_t; name: PUTF8Char; jsgf_string: PUTF8Char): Integer; cdecl; {** * Get the current Key phrase to spot @@ -154,7 +154,7 @@ function ps_set_jsgf_string(ps: pps_decoder_t; name: PUTF8Char; jsgf_string: PUT * * @return The current keyphrase to spot *} -function ps_get_kws(ps: pps_decoder_t; name: PUTF8Char): PUTF8Char; cdecl; external pocketsphinxlib; + Tps_get_kws = function (ps: pps_decoder_t; name: PUTF8Char): PUTF8Char; cdecl; {** * Adds keywords from a file to spotting @@ -164,7 +164,7 @@ function ps_get_kws(ps: pps_decoder_t; name: PUTF8Char): PUTF8Char; cdecl; exter * * @see ps_set_search *} -function ps_set_kws(ps: pps_decoder_t; name: PUTF8Char; keyfile: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_kws = function (ps: pps_decoder_t; name: PUTF8Char; keyfile: PUTF8Char): Integer; cdecl; {** * Adds new keyword to spot @@ -174,7 +174,7 @@ function ps_set_kws(ps: pps_decoder_t; name: PUTF8Char; keyfile: PUTF8Char): Int * * @see ps_set_search *} -function ps_set_keyphrase(ps: pps_decoder_t; name: PUTF8Char; keyphrase: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_keyphrase = function (ps: pps_decoder_t; name: PUTF8Char; keyphrase: PUTF8Char): Integer; cdecl; {** * Adds new search based on phone N-gram language model. @@ -184,7 +184,7 @@ function ps_set_keyphrase(ps: pps_decoder_t; name: PUTF8Char; keyphrase: PUTF8Ch * * @see ps_set_search. *} -function ps_set_allphone(ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t): Integer; cdecl; external pocketsphinxlib; + Tps_set_allphone = function (ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t): Integer; cdecl; {** * Adds new search based on phone N-gram language model. @@ -193,8 +193,60 @@ function ps_set_allphone(ps: pps_decoder_t; name: PUTF8Char; lm: pngram_model_t) * * @see ps_set_allphone *} -function ps_set_allphone_file(ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; external pocketsphinxlib; + Tps_set_allphone_file = function (ps: pps_decoder_t; name: PUTF8Char; path: PUTF8Char): Integer; cdecl; + +var + Lib: TLibHandle; + ps_set_search: Tps_set_search; + ps_get_search: Tps_get_search; + ps_unset_search: Tps_unset_search; + ps_search_iter: Tps_search_iter; + ps_search_iter_next: Tps_search_iter_next; + ps_search_iter_val: Tps_search_iter_val; + ps_search_iter_free: Tps_search_iter_free; + ps_get_lm: Tps_get_lm; + ps_set_lm: Tps_set_lm; + ps_set_lm_file: Tps_set_lm_file; + ps_get_fsg: Tps_get_fsg; + ps_set_fsg: Tps_set_fsg; + ps_set_jsgf_file: Tps_set_jsgf_file; + ps_set_jsgf_string: Tps_set_jsgf_string; + ps_get_kws: Tps_get_kws; + ps_set_kws: Tps_set_kws; + ps_set_keyphrase: Tps_set_keyphrase; + ps_set_allphone: Tps_set_allphone; + ps_set_allphone_file: Tps_set_allphone_file; implementation +procedure LoadLibrary; +begin + Lib := DynLibs.LoadLibrary(pocketsphinxlib); + if Lib <> DynLibs.NilHandle then + begin + ps_set_search := GetProcAddress(Lib, 'ps_set_search'); + ps_get_search := GetProcAddress(Lib, 'ps_get_search'); + ps_unset_search := GetProcAddress(Lib, 'ps_unset_search'); + ps_search_iter := GetProcAddress(Lib, 'ps_search_iter'); + ps_search_iter_next := GetProcAddress(Lib, 'ps_search_iter_next'); + ps_search_iter_val := GetProcAddress(Lib, 'ps_search_iter_val'); + ps_search_iter_free := GetProcAddress(Lib, 'ps_search_iter_free'); + ps_get_lm := GetProcAddress(Lib, 'ps_get_lm'); + ps_set_lm := GetProcAddress(Lib, 'ps_set_lm'); + ps_set_lm_file := GetProcAddress(Lib, 'ps_set_lm_file'); + ps_get_fsg := GetProcAddress(Lib, 'ps_get_fsg'); + ps_set_fsg := GetProcAddress(Lib, 'ps_set_fsg'); + ps_set_jsgf_file := GetProcAddress(Lib, 'ps_set_jsgf_file'); + ps_set_jsgf_string := GetProcAddress(Lib, 'ps_set_jsgf_string'); + ps_get_kws := GetProcAddress(Lib, 'ps_get_kws'); + ps_set_kws := GetProcAddress(Lib, 'ps_set_kws'); + ps_set_keyphrase := GetProcAddress(Lib, 'ps_set_keyphrase'); + ps_set_allphone := GetProcAddress(Lib, 'ps_set_allphone'); + ps_set_allphone_file := GetProcAddress(Lib, 'ps_set_allphone_file'); + end; +end; + +initialization + LoadLibrary; + end. diff --git a/src/uPocketSphinxBassAudioSource.pas b/src/uPocketSphinxBassAudioSource.pas index db8d935..c1face0 100644 --- a/src/uPocketSphinxBassAudioSource.pas +++ b/src/uPocketSphinxBassAudioSource.pas @@ -8,7 +8,7 @@ interface uses - Windows, Classes, SysUtils, Dialogs, uPocketSphinx, bass; + Classes, SysUtils, Dialogs, uPocketSphinx, bass; type @@ -39,6 +39,11 @@ function GetMicrophoneDeviceIdx: Integer; implementation +function HIWORD(l : longint) : WORD; +begin + HIWORD:=WORD(((DWORD(l)) shr 16) and $FFFF); +end; + { TBassAudioSource } function GetMicrophoneDeviceIdx: Integer; @@ -71,7 +76,7 @@ function TBassAudioSource.InitBASS(ADeviceIdx: Integer): Boolean; // Initialize audio device - 16000hz, mono, 16 bits Result := BASS_RecordInit(ADeviceIdx) and - BASS_Init(ADeviceIdx, 16000, BASS_DEVICE_MONO or BASS_DEVICE_FREQ, GetCurrentThread, nil); + BASS_Init(ADeviceIdx, 16000, BASS_DEVICE_MONO or BASS_DEVICE_FREQ, GetCurrentThreadID, nil); FBassInitialized := Result; end;