/** * You must sucessfully call spInitListener * once before using this function. * * Reads the next block of audio from the microphone * up to SPLBUFSIZE number of samples * (defined in splistener.h). * If an utterance was completed in that block, * the transcription is stored in the string words. * * When calling this function in a realtime loop, delay * by some amount of time between calls keeping in mind * your recording's sample rate and maximum samples read * per call (ex. sleep the thread for 100 milliseconds) * so that some audio can be recorded for the next call. * * @return true if a speech session was completed and * transcribed this block, otherwise false. */ static bool spDecode() { static bool uttered = false; // lock pocketsphinx resources to make sure they // don't get freed by main thread while in use std::lock_guard<std::mutex> ps_lock(ps_mtx); if(!mic || !ps) return false; int samples_read = ad_read(mic, buf, SPLBUFSIZE); if (samples_read <= 0) { spError("failed to read audio :("); return false; } ps_process_raw(ps, buf, samples_read, FALSE, FALSE); bool talking = ps_get_in_speech(ps); // Just started talking if (talking && !uttered) { uttered = true; return false; } // Stopped talking, so transcribe what was said // and begin the next utterance if (!talking && uttered) { ps_end_utt(ps); const char *trans = ps_get_hyp(ps, NULL); if (ps_start_utt(ps) < 0) { spError("failed to start utterance :("); } uttered = false; int l = strlen(trans); if (trans && l > 0) { std::lock_guard<std::mutex> lock(words_mtx); if (words && l + 1 > words_buf_size) { delete words; words = NULL; } if (!words) { words = new char[l + 1]; words_buf_size = l + 1; } std::copy(trans, trans + l, words); words[l] = '\0'; return true; } } return false; }
/* * SMPzeroRow() */ int SMPzeroRow(SMPmatrix *eMatrix, int Row) { MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Element; Row = Matrix->ExtToIntColMap[Row]; if (Matrix->RowsLinked == NO) spcLinkRows(Matrix); if (Matrix->PreviousMatrixWasComplex || Matrix->Complex) { for (Element = Matrix->FirstInRow[Row]; Element != NULL; Element = Element->NextInRow) { Element->Real = 0.0; Element->Imag = 0.0; } } else { for (Element = Matrix->FirstInRow[Row]; Element != NULL; Element = Element->NextInRow) { Element->Real = 0.0; } } return spError( (void *)Matrix ); }
/* * SMPcAddCol() */ int SMPcAddCol(SMPmatrix *eMatrix, int Accum_Col, int Addend_Col) { MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Accum, Addend, *Prev; Accum_Col = Matrix->ExtToIntColMap[Accum_Col]; Addend_Col = Matrix->ExtToIntColMap[Addend_Col]; Addend = Matrix->FirstInCol[Addend_Col]; Prev = &Matrix->FirstInCol[Accum_Col]; Accum = *Prev;; while (Addend != NULL) { while (Accum && Accum->Row < Addend->Row) { Prev = &Accum->NextInCol; Accum = *Prev; } if (!Accum || Accum->Row > Addend->Row) { Accum = spcCreateElement(Matrix, Addend->Row, Accum_Col, Prev, 0); } Accum->Real += Addend->Real; Accum->Imag += Addend->Imag; Addend = Addend->NextInCol; } return spError( (void *)Matrix ); }
/* * SMPcProdDiag() * note: obsolete for Spice3d2 and later */ int SMPcProdDiag(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent) { spDeterminant( (void *)Matrix, pExponent, &(pMantissa->real), &(pMantissa->imag) ); return spError( (void *)Matrix ); }
/* * SMPcZeroCol() */ int SMPcZeroCol(SMPmatrix *eMatrix, int Col) { MatrixPtr Matrix = (MatrixPtr)eMatrix; ElementPtr Element; Col = Matrix->ExtToIntColMap[Col]; for (Element = Matrix->FirstInCol[Col]; Element != NULL; Element = Element->NextInCol) { Element->Real = 0.0; Element->Imag = 0.0; } return spError( (void *)Matrix ); }
/* * SMPcDProd() */ int SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent) { double re, im, x, y, z; int p; spDeterminant( (void *)Matrix, &p, &re, &im); #ifndef M_LN2 #define M_LN2 0.69314718055994530942 #endif #ifndef M_LN10 #define M_LN10 2.30258509299404568402 #endif #ifdef debug_print printf("Determinant 10: (%20g,%20g)^%d\n", re, im, p); #endif /* Convert base 10 numbers to base 2 numbers, for comparison */ y = p * M_LN10 / M_LN2; x = (int) y; y -= x; /* ASSERT * x = integral part of exponent, y = fraction part of exponent */ /* Fold in the fractional part */ #ifdef debug_print printf(" ** base10 -> base2 int = %g, frac = %20g\n", x, y); #endif z = pow(2.0, y); re *= z; im *= z; #ifdef debug_print printf(" ** multiplier = %20g\n", z); #endif /* Re-normalize (re or im may be > 2.0 or both < 1.0 */ if (re != 0.0) { y = logb(re); if (im != 0.0) z = logb(im); else z = 0; } else if (im != 0.0) { z = logb(im); y = 0; } else { /* Singular */ /*printf("10 -> singular\n");*/ y = 0; z = 0; } #ifdef debug_print printf(" ** renormalize changes = %g,%g\n", y, z); #endif if (y < z) y = z; *pExponent = x + y; x = scalbn(re, (int) -y); z = scalbn(im, (int) -y); #ifdef debug_print printf(" ** values are: re %g, im %g, y %g, re' %g, im' %g\n", re, im, y, x, z); #endif pMantissa->real = scalbn(re, (int) -y); pMantissa->imag = scalbn(im, (int) -y); #ifdef debug_print printf("Determinant 10->2: (%20g,%20g)^%d\n", pMantissa->real, pMantissa->imag, *pExponent); #endif return spError( (void *)Matrix ); }
/* * SMPpreOrder() */ int SMPpreOrder(SMPmatrix *Matrix) { spMNA_Preorder( (void *)Matrix ); return spError( (void *)Matrix ); }
/* * SMPaddElt() */ int SMPaddElt(SMPmatrix *Matrix, int Row, int Col, double Value) { *spGetElement( (void *)Matrix, Row, Col ) = Value; return spError( (void *)Matrix ); }