@@ -95,6 +95,97 @@ export const main = async (settings) => {
9595 endOffset = nb . Words . slice ( - 1 ) [ 0 ] . Offset + nb . Words . slice ( - 1 ) [ 0 ] . Duration + 100000 ;
9696 } ;
9797
98+ function convertReferenceWords ( referenceText , referenceWords ) {
99+ const dictionary = [ ...new Set ( referenceWords ) ] ;
100+ const maxLength = Math . max ( ...dictionary . map ( word => word . length ) ) ;
101+
102+ // From left to right to do the longest matching to get the word segmentation
103+ function leftToRightSegmentation ( text , dictionary ) {
104+ var result = [ ] ;
105+ while ( text . length > 0 ) {
106+ let subText = "" ;
107+ // If the length of the text is less than the maxLength, then the subText is the text itself
108+ if ( text . length < maxLength ) {
109+ subText = text ;
110+ } else {
111+ subText = text . substring ( 0 , maxLength ) ;
112+ }
113+ while ( subText . length > 0 ) {
114+ // If the subText is in the dictionary or the length of the subText is 1, then add it to the result
115+ if ( dictionary . includes ( subText ) || subText . length === 1 ) {
116+ result . push ( subText ) ;
117+ // Remove the subText from the text
118+ text = text . slice ( subText . length ) ;
119+ break ;
120+ } else {
121+ // If the subText is not in the dictionary, then remove the last character of the subText
122+ subText = subText . slice ( 0 , - 1 ) ;
123+ }
124+ }
125+ }
126+ return result ;
127+ }
128+
129+ // From right to left to do the longest matching to get the word segmentation
130+ function rightToLeftSegmentation ( text , dictionary ) {
131+ var result = [ ] ;
132+ while ( text . length > 0 ) {
133+ let subText = "" ;
134+ // If the length of the text is less than the maxLength, then the subText is the text itself
135+ if ( text . length < maxLength ) {
136+ subText = text ;
137+ } else {
138+ subText = text . slice ( - maxLength ) ;
139+ }
140+ while ( subText . length > 0 ) {
141+ // If the subText is in the dictionary or the length of the subText is 1, then add it to the result
142+ if ( dictionary . includes ( subText ) || subText . length === 1 ) {
143+ result . push ( subText ) ;
144+ // Remove the subText from the text
145+ text = text . slice ( 0 , - subText . length ) ;
146+ break
147+ } else {
148+ // If the subText is not in the dictionary, then remove the first character of the subText
149+ subText = subText . slice ( 1 ) ;
150+ }
151+ }
152+ }
153+ // Reverse the result to get the correct order
154+ result = result . reverse ( ) ;
155+ return result ;
156+ }
157+
158+ function segment_word ( referenceText , dictionary ) {
159+ const leftToRight = leftToRightSegmentation ( referenceText , dictionary ) ;
160+ const rightToLeft = rightToLeftSegmentation ( referenceText , dictionary ) ;
161+ if ( leftToRight . join ( "" ) === referenceText ) {
162+ return leftToRight ;
163+ } else if ( rightToLeft . join ( "" ) === referenceText ) {
164+ return rightToLeft ;
165+ } else {
166+ console . log ( "WW failed to segment the text with the dictionary" )
167+ if ( leftToRight . length < rightToLeft . length ) {
168+ return leftToRight ;
169+ } else if ( leftToRight . length > rightToLeft . length ) {
170+ return rightToLeft ;
171+ } else {
172+ // If the word number is the same, then return the one with the smallest single word
173+ const leftToRightSingle = leftToRight . filter ( word => word . length === 1 ) . length ;
174+ const rightToLeftSingle = rightToLeft . filter ( word => word . length === 1 ) . length ;
175+ if ( leftToRightSingle < rightToLeftSingle ) {
176+ return leftToRight ;
177+ } else {
178+ return rightToLeft ;
179+ }
180+ }
181+ }
182+ }
183+
184+ // Remove punctuation from the reference text
185+ referenceText = referenceText . split ( "" ) . filter ( char => / [ \p{ L} \p{ N} \s ] / u. test ( char ) ) . join ( "" ) ;
186+ return segment_word ( referenceText , dictionary ) ;
187+ }
188+
98189 async function getReferenceWords ( waveFilename , referenceText , language ) {
99190 const audioConfig = sdk . AudioConfig . fromWavFileInput ( fs . readFileSync ( waveFilename ) ) ;
100191 const speechConfig = sdk . SpeechConfig . fromSubscription ( settings . subscriptionKey , settings . serviceRegion ) ;
@@ -131,7 +222,7 @@ export const main = async (settings) => {
131222 console . log ( `Speech Recognition canceled: ${ result . errorDetails } ` ) ;
132223 reject ( [ ] ) ;
133224 }
134- resolve ( referenceWords ) ;
225+ resolve ( convertReferenceWords ( referenceText , referenceWords ) ) ;
135226 speechRecognizer . close ( ) ;
136227 } ,
137228 ( err ) => {
0 commit comments