How do you stop sound playback in Garry's Mod? - garrys-mod

in this case, i want to stop function that's running
Example
local function X()
Play("Hello.mp3")
end
I want new function(let's call it Function Y) to stop function X while it still play the sound
Any ideas?!

Instead of relying on surface.PlaySound() which provides no way to cancel sound playback, use CreateSound which returns a sound object.
You can start/stop the playback with the following client-side code:
sound = CreateSound(game.GetWorld(), "Hello.mp3")
sound:Play()
sound:Stop()

Related

MacOS not responding to MPRemoteCommandCenter commands in the background

I am writing an application for my own purposes that aims to get play pause events no matter what is going on in the system. I have gotten this much working
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("Play Pause Command")
return .success
}
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("NextTrackCommand")
return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("previousTrackCommand")
return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("playCommand")
return .success
}
MPNowPlayingInfoCenter.default().playbackState = .playing
Most of those methods are there because apparently you will not get any notifications without having nextTrackCommand or previousTrackCommand or playCommand implemented.
Anyways my one issue is that as soon as you open another application that uses audio these event handlers stop getting called and I cant find a way to detect and fix this.
I would normally try doing AVAudioSession things to state this as a background application however that does not seem to work. Any ideas on how I can get playpause events no matter what state the system is in?
I would like to be able to always listen for these events OR get an indication of when someone else has taken control of the audio? Perhaps even be able to re-subscribe to these play pause events.
There's an internal queue in the system which contains all the audio event subscribers. Other applications get on top of it when you start using them.
I would like to be able to always listen for these events
There's no API for that but there's a dirty workaround. If I understand your issue correctly, this snippet:
MPNowPlayingInfoCenter.default().playbackState = .paused
MPNowPlayingInfoCenter.default().playbackState = .playing
must do the trick for you if you run it in a loop somewhere in your application.
Note that this is not 100% reliable because:
If an event is generated before two subsequent playbackState state changes right after you've switched to a different application, it would still be catched by the application in the active window;
If another application is doing the same thing, there would be a constant race condition in the queue, with unpredictable outcome.
References:
Documentation for playbackState is here;
See also a similar question;
See also a bug report for mpv with a similar
issue (a pre-MPRemoteCommandCenter one, but still very valuable)
OR get an indication of when someone else has taken control of the audio
As far as I know there's no public API for this in macOS.

QSound play sounds one after another

I'm working on a program that receive an event every 200ms, and I want to play a sound depending on the last event received when the last sound playing is finished.
Unfortunately the isFinished() function doesn't work on windows for unlooped sounds.
So I'm trying to find a way to wait until a sound has finished playing before playing an other one from the last event (like a LIFO with only one element).
I manage to do that :
QSound *sound[5];
int select, lastSelect;
if(sound[lastSelect]->loopsRemaining() >=1)
sound[lastSelect]->stop();
else {
sound[select]->setLoops(2);
sound[select]->play();
lastSelect = select;
}
But it's queuing the sounds and that's not what I want.
Otherwise I can do it by setting the number of loop to 2 but it plays the sound twice before playing the next one.
Do you have any idea how to do it ?

why does Parse cloud code save one object but not the other?

I am new to Parse Cloud Code.. however I am trying something that theoretically should be straight forward and I cannot understand why it won't work!
in my User class i have an array of playableFriends, when i create a Game object I wish to remove the player and opponent from each others playableFriends Array
The code to remove the opponent from the players array works.. but for some reason unknown to me the code to remove the player from the opponents array does not.. even if it is the only code being run.
I have output the player and opponent objects to the console to ensure they exist and I have also tried using the fetch command on the opponent but that didn't work either
Parse.Cloud.afterSave("Game",function(request, response){
//return if existing game
if (request.object.existed()){
return;
}
//get player
var player = request.object.get("playerIdle");
//get opponent
var opponent = request.object.get("playerTurn");
//remove opponent as playable friend
player.remove("playableFriends", opponent);
//remove player as opponents playable friend
opponent.remove("playableFriends", player);
player.save();
opponent.save();
});
any help would be greatly appreciated
regards
Byron
The problem is that the two save operations at the end of your functions are asynchronous. Basically, this means that when your player.save(); is reached, the execution continues on to the next line even though your save operation may not have completed (in your case it seems that it's the second save that is not completed). There are a couple ways of overcoming this: callbacks and promises.
A callback is a block of code that is passed into your async function that will be executed when the function completes. A promise, on the other hand, allows you to be notified when an async function completes. With promises, you use the then() function to continue execution once the original promise is fulfilled, which can either be resolved if the async operation was successful, or rejected if the async operation returned an error. Using promises, the last two lines of your function could be adapted as follows:
player.save().then( function(result){
return opponent.save();
}, function (error){
// We had an error saving the player
}).then( function(result){
console.log("Successfully saved user and opponent");
}, function(error){
// We had an error saving the opponent
});
I suggest you read up on both callbacks and promises as asynchronous functions are a fundamental part of working in the Parse Cloud Code environment. This blog post would be a great place to start. Callbacks may be easier to understand in the short term, but may lead to code that is harder to understand and maintain as your application grows in complexity.
EDIT
Since the ACLs on your opponent user restrict write operations to only that user, you'll also need to use the master key when saving that objects.

Setting a timeout for av_read_frame

I am new to FFMPEG and was trying to do HLS streaming using FFMPEG. When i tried using the function "av_read_frame" it returns a negative value whenever data is not available. Is there some method to make this function wait till some data is received or to make this function wait till a timeout is reached?
No, there really isn't. If you look at the simple player ffplay.c which comes with FFmpeg, the read_thread function basically loops on av_read_frame until it returns a non-negative return code. If it returns a negative value, it simply waits for 10ms and retries.

Attaching a callback to the output element of the Remote IO

I want to capture audio from the microphone of an iOS device and write it to a .caf file.
I'm able to connect a Remote IO audio unit to a multichannel mixer unit (MCMU) and attach a callback to the input of the MCMU. Inside that callback I can successfully write the audio data from the mic to a file using ExtAudioFileAsyncWrite().
I want to simplify things and remove the MCMU from the picture. My thinking is I can simply attach a callback to the output bus of the Remote IO's input scope and inside that callback call ExtAudioFileAsyncWrite().
However when I try this ExtAudioFileAsyncWrite() returns a -50 (paramError).
Is it not possible to attach a callback to the output bus of the input element of the Remote IO?
It is possible. You'll want to use AudioUnitSetProperty to set the kAudioOutputUnitProperty_SetInputCallback property. This callback will function much like a render callback, but will be called whenever the RemoteIO / mic has some new data for you (instead of as a request for data from your program).
Example:
AURenderCallbackStruct callbackInfo = {YourInputCallback, NULL};
AudioUnitSetProperty(remoteIO,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callbackInfo,
sizeof(callbackInfo));
This will make the RemoteIO / mic call YourInputCallback whenever it has a new batch of samples. You can use this callback to call ExtAudioFileWriteAsync as you did before. Note that you'll have to call AudioUnitRender on the RemoteIO as well, to get the new samples out of it.
Regarding the -50 error, that's not a very helpful error diagnostic. It basically just says "there was an error with one of your parameters". Most likely your ExtAudioFile was NULL or not set up properly (in which case, one of the ExtAudioFile* functions you used on it earlier would have returned a more helpful error code you can use to diagnose it).

Resources