33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { Disposable } from 'vs/base/common/lifecycle' ;
6+ import { Disposable , IDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
77import { FileAccess } from 'vs/base/common/network' ;
88import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility' ;
99import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
@@ -22,6 +22,8 @@ export interface IAudioCueService {
2222 onEnabledChanged ( cue : AudioCue ) : Event < void > ;
2323
2424 playSound ( cue : Sound , allowManyInParallel ?: boolean ) : Promise < void > ;
25+ playAudioCueLoop ( cue : AudioCue , milliseconds : number ) : IDisposable ;
26+ playRandomAudioCue ( groupId : AudioCueGroupId , allowManyInParallel ?: boolean ) : void ;
2527}
2628
2729export class AudioCueService extends Disposable implements IAudioCueService {
@@ -51,6 +53,12 @@ export class AudioCueService extends Disposable implements IAudioCueService {
5153 await Promise . all ( Array . from ( sounds ) . map ( sound => this . playSound ( sound , true ) ) ) ;
5254 }
5355
56+ public playRandomAudioCue ( groupId : AudioCueGroupId , allowManyInParallel ?: boolean ) : void {
57+ const cues = AudioCue . allAudioCues . filter ( cue => cue . groupId === groupId ) ;
58+ const index = Math . floor ( Math . random ( ) * cues . length ) ;
59+ this . playAudioCue ( cues [ index ] , allowManyInParallel ) ;
60+ }
61+
5462 private getVolumeInPercent ( ) : number {
5563 const volume = this . configurationService . getValue < number > ( 'audioCues.volume' ) ;
5664 if ( typeof volume !== 'number' ) {
@@ -66,7 +74,6 @@ export class AudioCueService extends Disposable implements IAudioCueService {
6674 if ( ! allowManyInParallel && this . playingSounds . has ( sound ) ) {
6775 return ;
6876 }
69-
7077 this . playingSounds . add ( sound ) ;
7178 const url = FileAccess . asBrowserUri ( `vs/platform/audioCues/browser/media/${ sound . fileName } ` ) . toString ( true ) ;
7279
@@ -87,6 +94,23 @@ export class AudioCueService extends Disposable implements IAudioCueService {
8794 }
8895 }
8996
97+ public playAudioCueLoop ( cue : AudioCue , milliseconds : number ) : IDisposable {
98+ let playing = true ;
99+ const playSound = ( ) => {
100+ if ( playing ) {
101+ this . playAudioCue ( cue , true ) . finally ( ( ) => {
102+ setTimeout ( ( ) => {
103+ if ( playing ) {
104+ playSound ( ) ;
105+ }
106+ } , milliseconds ) ;
107+ } ) ;
108+ }
109+ } ;
110+ playSound ( ) ;
111+ return toDisposable ( ( ) => playing = false ) ;
112+ }
113+
90114 private readonly obsoleteAudioCuesEnabled = observableFromEvent (
91115 Event . filter ( this . configurationService . onDidChangeConfiguration , ( e ) =>
92116 e . affectsConfiguration ( 'audioCues.enabled' )
@@ -190,19 +214,30 @@ export class Sound {
190214 public static readonly diffLineInserted = Sound . register ( { fileName : 'diffLineInserted.mp3' } ) ;
191215 public static readonly diffLineDeleted = Sound . register ( { fileName : 'diffLineDeleted.mp3' } ) ;
192216 public static readonly diffLineModified = Sound . register ( { fileName : 'diffLineModified.mp3' } ) ;
217+ public static readonly chatRequestSent = Sound . register ( { fileName : 'chatRequestSent.mp3' } ) ;
218+ public static readonly chatResponsePending = Sound . register ( { fileName : 'chatResponsePending.mp3' } ) ;
219+ public static readonly chatResponseReceived1 = Sound . register ( { fileName : 'chatResponseReceived1.mp3' } ) ;
220+ public static readonly chatResponseReceived2 = Sound . register ( { fileName : 'chatResponseReceived2.mp3' } ) ;
221+ public static readonly chatResponseReceived3 = Sound . register ( { fileName : 'chatResponseReceived3.mp3' } ) ;
222+ public static readonly chatResponseReceived4 = Sound . register ( { fileName : 'chatResponseReceived4.mp3' } ) ;
223+ public static readonly chatResponseReceived5 = Sound . register ( { fileName : 'chatResponseReceived5.mp3' } ) ;
193224
194225 private constructor ( public readonly fileName : string ) { }
195226}
196227
228+ export const enum AudioCueGroupId {
229+ chatResponseReceived = 'chatResponseReceived'
230+ }
231+
197232export class AudioCue {
198233 private static _audioCues = new Set < AudioCue > ( ) ;
199-
200234 private static register ( options : {
201235 name : string ;
202236 sound : Sound ;
203237 settingsKey : string ;
238+ groupId ?: AudioCueGroupId ;
204239 } ) : AudioCue {
205- const audioCue = new AudioCue ( options . sound , options . name , options . settingsKey ) ;
240+ const audioCue = new AudioCue ( options . sound , options . name , options . settingsKey , options . groupId ) ;
206241 AudioCue . _audioCues . add ( audioCue ) ;
207242 return audioCue ;
208243 }
@@ -309,9 +344,53 @@ export class AudioCue {
309344 settingsKey : 'audioCues.diffLineModified'
310345 } ) ;
311346
347+ public static readonly chatRequestSent = AudioCue . register ( {
348+ name : localize ( 'audioCues.chatRequestSent' , 'Chat Request Sent' ) ,
349+ sound : Sound . chatRequestSent ,
350+ settingsKey : 'audioCues.chatRequestSent'
351+ } ) ;
352+
353+ public static readonly chatResponseReceived = {
354+ name : localize ( 'audioCues.chatResponseReceived' , 'Chat Response Received' ) ,
355+ settingsKey : 'audioCues.chatResponseReceived' ,
356+ groupId : AudioCueGroupId . chatResponseReceived
357+ } ;
358+
359+ public static readonly chatResponseReceived1 = AudioCue . register ( {
360+ sound : Sound . chatResponseReceived1 ,
361+ ...this . chatResponseReceived
362+ } ) ;
363+
364+ public static readonly chatResponseReceived2 = AudioCue . register ( {
365+ sound : Sound . chatResponseReceived2 ,
366+ ...this . chatResponseReceived
367+ } ) ;
368+
369+ public static readonly chatResponseReceived3 = AudioCue . register ( {
370+ sound : Sound . chatResponseReceived3 ,
371+ ...this . chatResponseReceived
372+ } ) ;
373+
374+ public static readonly chatResponseReceived4 = AudioCue . register ( {
375+ sound : Sound . chatResponseReceived4 ,
376+ ...this . chatResponseReceived
377+ } ) ;
378+
379+ public static readonly chatResponseReceived5 = AudioCue . register ( {
380+ sound : Sound . chatResponseReceived5 ,
381+ ...this . chatResponseReceived
382+ } ) ;
383+
384+ public static readonly chatResponsePending = AudioCue . register ( {
385+ name : localize ( 'audioCues.chatResponsePending' , 'Chat Response Pending' ) ,
386+ sound : Sound . chatResponsePending ,
387+ settingsKey : 'audioCues.chatResponsePending'
388+ } ) ;
389+
312390 private constructor (
313391 public readonly sound : Sound ,
314392 public readonly name : string ,
315393 public readonly settingsKey : string ,
394+ public readonly groupId ?: string
316395 ) { }
317396}
0 commit comments