Fixed the native audio playback
This commit is contained in:
		
							parent
							
								
									fe947ea83b
								
							
						
					
					
						commit
						0a6c68f940
					
				| @ -10,6 +10,7 @@ import {processArguments} from "../../shared/process-arguments"; | ||||
| 
 | ||||
| import "./ExternalModal"; | ||||
| import {showUpdateWindow} from "../windows/client-updater/controller/ClientUpdate"; | ||||
| import {getUiFilePath} from "../ui-loader/Loader"; | ||||
| 
 | ||||
| ipcMain.on('basic-action', (event, action, ...args: any[]) => { | ||||
|     const window = BrowserWindow.fromWebContents(event.sender); | ||||
| @ -28,3 +29,5 @@ ipcMain.on('basic-action', (event, action, ...args: any[]) => { | ||||
|         window.close(); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| ipcMain.handle("tc-get-ui-path", () => getUiFilePath()); | ||||
| @ -125,8 +125,14 @@ async function unpackLocalUiPack(version: CachedUIPack) : Promise<string> { | ||||
|     return targetDirectory; | ||||
| } | ||||
| 
 | ||||
| let uiFilePath: string; | ||||
| export function getUiFilePath() : string | undefined { | ||||
|     return uiFilePath; | ||||
| } | ||||
| 
 | ||||
| function initializeFileSystemProtocol(directory: string) { | ||||
|     directory = path.normalize(directory); | ||||
|     uiFilePath = directory; | ||||
| 
 | ||||
|     protocol.registerFileProtocol(kUiPackProtocol, (request, callback) => { | ||||
|         let targetPath; | ||||
|  | ||||
| @ -1,27 +1,52 @@ | ||||
| import {audio as naudio} from "tc-native/connection"; | ||||
| import {SoundBackend, SoundFile} from "tc-shared/audio/Sounds"; | ||||
| import * as paths from "path"; | ||||
| import * as loader from "tc-loader"; | ||||
| import {Stage} from "tc-loader"; | ||||
| import {ipcRenderer} from "electron"; | ||||
| import {LogCategory, logDebug, logInfo} from "tc-shared/log"; | ||||
| 
 | ||||
| let uiFilePath; | ||||
| export class NativeSoundBackend implements SoundBackend { | ||||
|     playSound(sound: SoundFile): Promise<void> { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             let pathname = paths.dirname(decodeURIComponent(location.pathname)); | ||||
|             if(pathname[0] === '/' && pathname[2] === ':') //e.g.: /C:/test...
 | ||||
|                 pathname = pathname.substr(1); | ||||
|             const path = paths.join(pathname, sound.path); | ||||
|             if(!uiFilePath) { | ||||
|                 reject("Mussing UI file path"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             console.log("replaying %s (volume: %f)", sound.path, sound.volume); | ||||
|             const path = paths.join(uiFilePath, sound.path); | ||||
|             console.log("replaying %s (volume: %f) from %s", sound.path, sound.volume, path); | ||||
|             naudio.sounds.playback_sound({ | ||||
|                 callback: (result, message) => { | ||||
|                     if(result == naudio.sounds.PlaybackResult.SUCCEEDED) | ||||
|                     if(result == naudio.sounds.PlaybackResult.SUCCEEDED) { | ||||
|                         resolve(); | ||||
|                     else | ||||
|                     } else { | ||||
|                         reject(naudio.sounds.PlaybackResult[result].toLowerCase() + ": " + message); | ||||
|                     } | ||||
|                 }, | ||||
|                 file: path, | ||||
|                 volume: typeof sound.volume === "number" ? sound.volume : 1 | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| //tc-get-ui-path
 | ||||
| loader.register_task(Stage.JAVASCRIPT_INITIALIZING, { | ||||
|     name: "sound initialize", | ||||
|     priority: 50, | ||||
|     function: async () => { | ||||
|         uiFilePath = await ipcRenderer.invoke("tc-get-ui-path"); | ||||
|         if(!uiFilePath) { | ||||
|             logInfo(LogCategory.AUDIO, tr("Missing UI path. App sounds will not work.")); | ||||
|         } else { | ||||
|             if(uiFilePath[0] === '/' && uiFilePath[2] === ':') { | ||||
|                 //e.g.: /C:/test...
 | ||||
|                 uiFilePath = uiFilePath.substr(1); | ||||
|             } | ||||
| 
 | ||||
|             logDebug(LogCategory.AUDIO, tr("Received UI path: %s"), uiFilePath); | ||||
|         } | ||||
|     } | ||||
| }) | ||||
| @ -270,7 +270,7 @@ ssize_t AudioOutputSource::enqueue_samples_no_interleave(const void *source_buff | ||||
| bool AudioOutputSource::set_max_buffered_samples(size_t samples) { | ||||
|     samples = std::max(samples, (size_t) this->fadein_frame_samples_); | ||||
|     if(samples > this->max_supported_buffering()) { | ||||
|         return false; | ||||
|         samples = this->max_supported_buffering(); | ||||
|     } | ||||
| 
 | ||||
|     std::lock_guard buffer_lock{this->buffer_mutex}; | ||||
|  | ||||
| @ -87,8 +87,9 @@ namespace tc::audio::sounds { | ||||
|                     this->file_handle = std::make_unique<file::WAVReader>(this->settings_.file); | ||||
|                     std::string error{}; | ||||
|                     if(auto err{this->file_handle->open_file(error)}; err != file::OPEN_RESULT_SUCCESS) { | ||||
|                         if(auto callback{this->settings_.callback}; callback) | ||||
|                         if(auto callback{this->settings_.callback}; callback) { | ||||
|                             callback(PlaybackResult::FILE_OPEN_ERROR, error); | ||||
|                         } | ||||
|                         this->finalize(false); | ||||
|                         return; | ||||
|                     } | ||||
| @ -175,21 +176,27 @@ namespace tc::audio::sounds { | ||||
|                 auto weak_this = this->weak_from_this(); | ||||
|                 this->output_source->on_underflow = [weak_this](size_t sample_count){ | ||||
|                     auto self = weak_this.lock(); | ||||
|                     if(!self) return false; | ||||
|                     if(!self) { | ||||
|                         return false; | ||||
|                     } | ||||
| 
 | ||||
|                     if(self->state_ == PLAYER_STATE_PLAYING) | ||||
|                     if(self->state_ == PLAYER_STATE_PLAYING) { | ||||
|                         log_warn(category::audio, tr("Having an audio underflow while playing a sound.")); | ||||
|                     else if(self->state_ == PLAYER_STATE_AWAIT_FINISH) | ||||
|                     } else if(self->state_ == PLAYER_STATE_AWAIT_FINISH) { | ||||
|                         self->state_ = PLAYER_STATE_FINISHED; | ||||
|                     } | ||||
|                     audio::decode_event_loop->schedule(self); | ||||
|                     return false; | ||||
|                 }; | ||||
|                 this->output_source->on_read = [weak_this] { | ||||
|                     auto self = weak_this.lock(); | ||||
|                     if(!self) return; | ||||
|                     if(!self) { | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     if(self->could_enqueue_next_buffer() && self->state_ == PLAYER_STATE_PLAYING) | ||||
|                     if(self->could_enqueue_next_buffer() && self->state_ == PLAYER_STATE_PLAYING) { | ||||
|                         audio::decode_event_loop->schedule(self); | ||||
|                     } | ||||
|                 }; | ||||
| 
 | ||||
|                 this->output_source->on_overflow = [weak_this](size_t count) { | ||||
| @ -205,7 +212,9 @@ namespace tc::audio::sounds { | ||||
|             } | ||||
| 
 | ||||
|             [[nodiscard]] inline bool could_enqueue_next_buffer() const { | ||||
|                 if(!this->output_source) return false; | ||||
|                 if(!this->output_source) { | ||||
|                     return false; | ||||
|                 } | ||||
| 
 | ||||
|                 const auto current_size = this->output_source->currently_buffered_samples(); | ||||
|                 const auto max_size = this->output_source->max_buffered_samples(); | ||||
| @ -233,8 +242,9 @@ namespace tc::audio::sounds { | ||||
|         auto player = std::make_shared<FilePlayer>(settings); | ||||
|         file_players.push_back(player); | ||||
|         if(!player->play()) { | ||||
|             if(auto callback{settings.callback}; callback) | ||||
|             if(auto callback{settings.callback}; callback) { | ||||
|                 callback(PlaybackResult::PLAYBACK_ERROR, "failed to start playback."); | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|         fplock.unlock(); | ||||
| @ -244,7 +254,9 @@ namespace tc::audio::sounds { | ||||
|     void cancel_playback(const sound_playback_id& id) { | ||||
|         std::unique_lock fplock{file_player_mutex}; | ||||
|         auto player_it = std::find_if(file_players.begin(), file_players.end(), [&](const auto& player) { return (sound_playback_id) &*player == id; }); | ||||
|         if(player_it == file_players.end()) return; | ||||
|         if(player_it == file_players.end()) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         auto player = *player_it; | ||||
|         file_players.erase(player_it); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user