@@ -13,26 +13,16 @@ import { createTranscription } from "../db/transcriptions";
13
13
import { logger } from "../main/logger" ;
14
14
import { v4 as uuid } from "uuid" ;
15
15
import { VADService } from "./vad-service" ;
16
- import { app } from "electron" ;
17
- import * as fs from "node:fs" ;
18
- import * as path from "node:path" ;
19
-
20
- import { StreamingWavWriter } from "../utils/streaming-wav-writer" ;
21
16
import { Mutex } from "async-mutex" ;
22
17
23
18
/**
24
19
* Service for audio transcription and optional formatting
25
20
*/
26
- interface ExtendedStreamingSession extends StreamingSession {
27
- wavWriter ?: StreamingWavWriter ;
28
- audioFilePath ?: string ;
29
- }
30
-
31
21
export class TranscriptionService {
32
22
private whisperProvider : WhisperProvider ;
33
23
private openRouterProvider : OpenRouterProvider | null = null ;
34
24
private formatterEnabled = false ;
35
- private streamingSessions : Map < string , ExtendedStreamingSession > = new Map ( ) ;
25
+ private streamingSessions : Map < string , StreamingSession > = new Map ( ) ;
36
26
private vadService : VADService | null ;
37
27
private settingsService : SettingsService ;
38
28
private vadMutex : Mutex ;
@@ -143,35 +133,16 @@ export class TranscriptionService {
143
133
}
144
134
}
145
135
146
- /**
147
- * Create audio file for recording session
148
- */
149
- private async createAudioFile ( sessionId : string ) : Promise < string > {
150
- // Create audio directory in app temp path
151
- const audioDir = path . join ( app . getPath ( "temp" ) , "amical-audio" ) ;
152
- await fs . promises . mkdir ( audioDir , { recursive : true } ) ;
153
-
154
- // Create file path
155
- const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, "-" ) ;
156
- const filePath = path . join ( audioDir , `audio-${ sessionId } -${ timestamp } .wav` ) ;
157
-
158
- logger . transcription . info ( "Created audio file for session" , {
159
- sessionId,
160
- filePath,
161
- } ) ;
162
-
163
- return filePath ;
164
- }
165
-
166
136
/**
167
137
* Process a single audio chunk in streaming mode
168
138
*/
169
139
async processStreamingChunk ( options : {
170
140
sessionId : string ;
171
141
audioChunk : Float32Array ;
172
142
isFinal ?: boolean ;
143
+ audioFilePath ?: string ;
173
144
} ) : Promise < string > {
174
- const { sessionId, audioChunk, isFinal = false } = options ;
145
+ const { sessionId, audioChunk, isFinal = false , audioFilePath } = options ;
175
146
176
147
// Run VAD on the audio chunk
177
148
let speechProbability = 0 ;
@@ -198,6 +169,7 @@ export class TranscriptionService {
198
169
199
170
// Acquire transcription mutex
200
171
await this . transcriptionMutex . acquire ( ) ;
172
+
201
173
// Auto-create session if it doesn't exist
202
174
let session = this . streamingSessions . get ( sessionId ) ;
203
175
if ( ! session ) {
@@ -214,31 +186,18 @@ export class TranscriptionService {
214
186
streamingContext . sharedData . accessibilityContext =
215
187
appContextStore . getAccessibilityContext ( ) ;
216
188
217
- // Create audio file for this session
218
- const audioFilePath = await this . createAudioFile ( sessionId ) ;
219
-
220
- // Create streaming WAV writer
221
- const wavWriter = new StreamingWavWriter ( audioFilePath ) ;
222
-
223
189
session = {
224
190
context : streamingContext ,
225
191
transcriptionResults : [ ] ,
226
- audioFilePath,
227
- wavWriter,
228
192
} ;
229
193
230
194
this . streamingSessions . set ( sessionId , session ) ;
195
+
231
196
logger . transcription . info ( "Started streaming session" , {
232
197
sessionId,
233
- audioFilePath,
234
198
} ) ;
235
199
}
236
200
237
- // Write audio chunk to WAV file immediately
238
- if ( audioChunk . length > 0 && session . wavWriter ) {
239
- await session . wavWriter . appendAudio ( audioChunk ) ;
240
- }
241
-
242
201
// Process chunk if it has content
243
202
if ( audioChunk . length > 0 ) {
244
203
// Direct frame to Whisper - it will handle aggregation and VAD internally
@@ -285,7 +244,7 @@ export class TranscriptionService {
285
244
286
245
// Release transcription mutex
287
246
this . transcriptionMutex . release ( ) ;
288
- let completeTranscriptionTillNow = session . transcriptionResults
247
+ const completeTranscriptionTillNow = session . transcriptionResults
289
248
. join ( " " )
290
249
. trim ( ) ;
291
250
@@ -302,13 +261,11 @@ export class TranscriptionService {
302
261
chunkCount : session . transcriptionResults . length ,
303
262
} ) ;
304
263
305
- // Format if enabled (currently disabled with && false)
306
- // Commenting out to fix TypeScript errors since this code path is never executed
307
- /*
308
- if (this.formatterEnabled && this.openRouterProvider && false) {
264
+ if ( this . formatterEnabled && this . openRouterProvider ) {
265
+ try {
309
266
const style =
310
267
session . context . sharedData . userPreferences ?. formattingStyle ;
311
- completeTranscription = await this.openRouterProvider.format({
268
+ const formattedText = await this . openRouterProvider . format ( {
312
269
text : completeTranscription ,
313
270
context : {
314
271
style,
@@ -324,24 +281,31 @@ export class TranscriptionService {
324
281
aggregatedTranscription : completeTranscription ,
325
282
} ,
326
283
} ) ;
327
- }
328
- */
329
284
330
- // Finalize the WAV file
331
- if ( session . wavWriter ) {
332
- await session . wavWriter . finalize ( ) ;
333
- logger . transcription . info ( "Finalized WAV file" , {
334
- sessionId,
335
- filePath : session . audioFilePath ,
336
- dataSize : session . wavWriter . getDataSize ( ) ,
337
- } ) ;
285
+ logger . transcription . info ( "Text formatted successfully" , {
286
+ sessionId,
287
+ originalLength : completeTranscription . length ,
288
+ formattedLength : formattedText . length ,
289
+ } ) ;
290
+
291
+ completeTranscription = formattedText ;
292
+ } catch ( error ) {
293
+ logger . transcription . error (
294
+ "Formatting failed, using unformatted text" ,
295
+ {
296
+ sessionId,
297
+ error,
298
+ } ,
299
+ ) ;
300
+ // Continue with unformatted text
301
+ }
338
302
}
339
303
340
304
// Save directly to database
341
305
logger . transcription . info ( "Saving transcription with audio file" , {
342
306
sessionId,
343
- audioFilePath : session . audioFilePath ,
344
- hasAudioFile : ! ! session . audioFilePath ,
307
+ audioFilePath,
308
+ hasAudioFile : ! ! audioFilePath ,
345
309
} ) ;
346
310
347
311
await createTranscription ( {
@@ -350,7 +314,7 @@ export class TranscriptionService {
350
314
duration : session . context . sharedData . audioMetadata ?. duration ,
351
315
speechModel : "whisper-local" ,
352
316
formattingModel : this . formatterEnabled ? "openrouter" : undefined ,
353
- audioFile : session . audioFilePath ,
317
+ audioFile : audioFilePath ,
354
318
meta : {
355
319
sessionId,
356
320
source : session . context . sharedData . audioMetadata ?. source ,
0 commit comments