Getting a sound trigger to work - audio

I don't understand why my sound trigger is not working. I have created a GameObject and added an Audio Source to it (on Audio Source I have the Play On Wake and Loop checked. Then I added a Sphere Collider (I have the Is Trigger checked). Finally I added my script and added the sound clips into the inspector. Unity also says that: "There are 2 audio listeners in the scene." I have pretty much unchecked all the audio listeners and it still says it, what am I doing wrong?
Here is a look at my code:
#pragma strict
var WalkAudio:AudioClip;
var OutCry:AudioClip;
function Update (){
var Audio= gameObject.GetComponent(AudioSource);
if(Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
Audio.Play();
}
else
{
Audio.Pause();
}
}
function OnControllerColliderHit (hit : ControllerColliderHit)
{
var Audio= gameObject.GetComponent(AudioSource);
if (hit.gameObject.tag == "templeFloor")
{
var groundType = 1;
print("Temple");
Audio.clip=OutCry;
}
else{
Audio.clip=WalkAudio;
}
}

As you said:
I have pretty much unchecked all the audio listeners
The component AudioListener attached to the Main Camera must be enabled. Probably you have used LoadLevelAdditive so you have two camera and two AudioListener components, one on each of them. Please make sure this additive camera and any other gameObject should have this component disabled.
Also at runtime, you can search which component(s) have AudioListener component attached using this in the Hierarchy window search bar.
t:AudioListener
This should help you out. Also double check using Debug.Log that OnControllerColliderHit function calls and Audio.clip is not null after assignment. Also is it necessary to play sound in Update ?
Also, you should move this line from Update to Start function instead, due to performance cost:
var Audio= gameObject.GetComponent(AudioSource);
and use this Audio variable throughout your script.

Related

How do I turn the mic off?

I'm using navigator.getUserMedia for a voice memo app. It works like a charm.
When I quit the app, the microphone stays on (there is a notification "Audio Memos Mic is on" and the red dot remains in the status bar. It stays on even after the phone went to sleep for fifteen minutes.
How do I turn the mic off when I quit the app. I've check the mediastream API but couldn't find any reference.
Have you tried the stop method: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder.stop
There may be a better way but I got the light to turn off on minimized apps by using code similar to:
mediaRecorder was a ref to the MediaRecorder object tied to the stream. You can also just call stop on the stream returned by the GetUserMedia call. Also had to call setup on init of app as well.
function handleVisibilityChange() {
if (document.hidden) {
console.log("hidden");
if( gumStream ){
gumStream.stop();
mediaRecorder = null;
}
} else {
console.log("visible");
setup(); //Call getUserMedia
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);

AS3 load new URLRequest through a string

I want to load a new URL (which is in a array), everytime I press the button. I have the following code to do so:
public function selectRadio(radio:Radio):void {
var soundR:Sound = new Sound();
if(!playing) {
soundR.load(new URLRequest(radio.getURL()));
soundChannel = soundR.play();
playing = true;
}
else{
soundChannel.stop();
playing = false;
}
trace("You are now listening to " + radio.getTitle());
}
But it gives me this error:
"implicit coercion of a value of type flash.net:URLRequest to an unrelated type string"
It works if I just leave it like this:
soundR.load(radio.getURL());
But if i do so, I can only press play and stop 4 times. After the fourth there is no sound, like it can't load the URL.
Is it possible to fix this?
Radio.getURL() should return a string instead of a URLRequest?
Ah nevermind I see you tried avoiding that by removing URLRequest, but you are having problems with only 4 connections.
In all but the simplest cases, your application should pay attention to the sound’s loading progress and watch for errors during loading. For example, if the click sound is fairly large, it might not be completely loaded by the time the user clicks the button that triggers the sound. Trying to play an unloaded sound could cause a run-time error. It’s safer to wait for the sound to load completely before letting users take actions that might start sounds playing.
http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d25.html
If you can't wait for the sound to completely load you may need NetStream:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html

Best approach for playing a single tone audio file?

Can anyone tell me the best approach to playing single-tone, audio (.mp3) files in a Windows Phone 8 app? Think of a piano app, where each key would represent a button, and each button would play a different tone.
I'm looking for the most efficient way to go about this - I've got 8 different buttons that need to play a different tone when tapped.
I tried using the MediaElement:
MediaElement me;
public MainPage()
{
InitializeComponent();
me = new MediaElement();
me.AutoPlay = false;
me.Source = new Uri("/Sounds/Sound1.mp3", UriKind.Relative);
btnPlay.Click += btnPlay_Click;
}
private void btnPlay_Click(object sender, EventArgs e)
{
me.Play();
}
But nothing happens, either in the emulator or on a device (testing w/ a Lumia 822). Am I doing something wrong here? It seems like it should be pretty simple. Or would using MediaElement even be the best thing to use for my scenario?
Would this fall under the Background Audio category? I've read through this example but it seems overkill for what I want to do.
I've also read about using XNA's SoundEffect to do the job, but then I'd have to convert my .mp3 files to .wav (which isn't necessarily a problem, but I'd rather not go through that if I don't need to).
Can anyone tell me either what I'm doing wrong in my example above or guide me to a better solution for playing quick <1s audio tones?
I had this problem before with MediaElement not playing audio files. After many attempts I found out that it only plays if it defined in the xaml and AutoPlay is set to true.
Try defining it in the xaml or you can just add it to your LayoutRoot.
var me = new MediaElement();
LayoutRoot.Children.Add(me);
me.AutoPlay = true;
me.Source = new Uri("Sound/1.mp3", UriKind.Relative);
I have had good luck just doing this piece of code in my app. But it may not work as well in your context, give it a whirl though.
mediaElement.Source = new Uri("/Audio/" + songID.ToString() + ".mp3", UriKind.Relative);
mediaElement.Play();

FMOD surround sound openframeworks

Ok, I hope I don't mess this up, I have had a look for some answers but can't find anything. I am trying to make a simple sampler in openframeworks using the FMOD sound player in 3D mode. I can make a single instance work fine (recording a new file using libsndfilerecorder and then playing it back and moving it in surround.
However I want to have 8 layers of looping audio that I can record and replace one layer at a time in a live show. I get a lot of problems as soon as I have more than 1 layer.
The first part of my question relates to the FMOD 3D modes, it is listener relative, so I have to define the position of my listener for every sound (I would prefer to have head relative mode but I cannot make this work at all. Again this works fine when I am using a single player but with multiple players only the last listener I update actually works.
The main problem I have is that when I use multiple players I get distortion, and often a mix of other currently playing sounds (even when the microphone cannot hear them) in my new recordings. Is there an incompatability with libsndfilerecorder and FMOD?
Here I initialise the players
for (int i=0; i<CHANNEL_COUNT; i++) {
lvelocity[i].set(1, 1, 1);
lup[i].set(0, 1, 0);
lforward[i].set(0, 0, 1);
lposition[i].set(0, 0, 0);
sposition[i].set(3, 3, 2);
svelocity[i].set(1, 1, 1);
//player[1].initializeFmod();
//player[i].loadSound( "1.wav" );
player[i].setVolume(0.75);
player[i].setMultiPlay(true);
player[i].play();
setupHold[i]==false;
recording[i]=false;
channelHasFile[i]=false;
settingOsc[i]=false;
}
When I am recording I unload the file and make sure the positions of the player that is not loaded are not updating.
void fmodApp::recordingStart( int recordingId ){
if (recording[recordingId]==false) {
setupHold[recordingId]=true; //this stops the position updating
cout<<"Start recording Channel " + ofToString(recordingId+1)+" setup hold is true \n";
pt=getDateName() +".wav";
player[recordingId].stop();
player[recordingId].unloadSound();
audioRecorder.setup(pt);
audioRecorder.setFormat(SF_FORMAT_WAV | SF_FORMAT_PCM_16);
recording[recordingId]=true; //this starts the libSndFIleRecorder
}
else {
cout<<"Channel" + ofToString(recordingId+1)+" is already recording \n";
}
}
And I stop the recording like this.
void fmodApp::recordingEnd( int recordingId ){
if (recording[recordingId]=true) {
recording[recordingId]=false;
cout<<"Stop recording" + ofToString(recordingId+1)+" \n";
audioRecorder.finalize();
audioRecorder.close();
player[recordingId].loadSound(pt);
setupHold[recordingId]=false;
channelHasFile[recordingId]=true;
cout<< "File recorded channel " + ofToString(recordingId+1) + " file is called " + pt + "\n";
}
else {
cout << "Sorry track" + ofToString(recordingId+1) + "is not recording";
}
}
I am careful not to interrupt the updating process but I cannot see where I am going wrong.
Many Thanks
to deal with the distortion, i think you will need to lower the volume of each channel on playback, try setting the volume to 1/8 of the max volume. there isn't any clipping going on so if the sum of sounds > 1.0f you will clip and it will sound bad.
to deal with crosstalk when recording: i guess you have some sort of feedback going on with the output, ie the output sound is being fed back into the input channel, probably by the operating system. if you run another app that makes sound do you also get that in your recording as well? if so then that is probably your problem.
if it works with one channel, try it with just 2, instead of jumping straight up to 8 channels.
in general i would try to abstract out the playback/record logic and soundPlayer/recorder into a separate class. you have a couple of booleans there and it's really easy to make mistakes with >1 boolean. is there any way you can replace the booleans with an enum or an integer state variable?
EDIT: I didn't see the date on your question :D Suppose you managed to do it by now. Maybe it helps somebody else..
I'm not sure if I can answer everything of your question, but I can share how I've worked with 3D sound in FMOD. I haven't worked with recording though.
For my own application a user can place sounds in 3D space around himself. For this I only have one Listener and multiple Sounds. In your code you're making a listener for every sound, are you sure that is necessary? I would imagine that this causes the multiple listeners to pick up multiple sounds and output that to your soundcard. So from the second sound+listener, both listeners pick up both sounds? I'm not a 100% sure but it sounds plausible to me.
I made a class to create sound objects (and one listener). Then I use a vector to store the objects and move trough them to render them.
My class SoundBox basically holds all the necessary things for FMOD
Making a "SoundBox" object and adding it to my soundboxes vector:
SoundBox * box = new SoundBox(box_loc, box_rotation, box_color);
box->loadVideo(ofToDataPath(video_files[soundboxes.size()]));
box->loadSound(ofToDataPath(sound_files[soundboxes.size()]));
box->setVolume(1);
box->setMultiPlay(true);
box->updateSound(box_loc, box_vel);"
box->play();
soundboxes.push_back(box);
Constructor for the SoundBox. I use a similar constructor in the same class for the listener, but since the listener will always be at the origin for me, it doesn't take any arguments and just sets all the listener locations to 0. The constructor for the listener only gets called once, while the one for the Sound gets called whenever I want to make a new one. (don't mind the box_color. I'm drawing physical boxes in this case..):
SoundBox::SoundBox(ofVec3f box_location, ofVec3f box_rotation, ofColor box_color) {
_box_location = box_location;
_box_rotation = box_rotation;
_box_color = box_color;
sound_position.x = _box_location.x;
sound_position.y = _box_location.y;
sound_position.z = _box_location.z;
sound_velocity.x = 0;
sound_velocity.y = 0;
sound_velocity.z = 0;
Then I just use a for loop to loop trough them and play them if they're not playing. I also have some similar code to select them and move then around.
for(auto box = soundboxes.begin(); box != soundboxes.end(); box++){
if(!(*box)->getIsPlaying())
(*box)->play();
}
I really hoped this helped. I'm not a very experienced programmer but this is how I got FMOD with multiple sounds to work in OpenFrameworks and hope you can use some of it. I just dumped as much of my code as I could :D
My main suggestion is to make one listener instead of more. Also having a class for making the sounds is useful if you, for instance, want to relocate the sounds after the initial placement.
Hope it helps and good luck :)

specific motion tween stop & resume

I'm new in games development, am trying to create a simple game in flash-cs5. I created 3 motion tweens in timeline. i'm trying to stop a specific motion tween, when that tween's movieclip is clicked while other tweeens are running and also when the stopped movieclip is clicked again i want to resume the tween while other tweeens are running.
thanking in advanced.
The following is assuming you have each motion tween inside its own movieclip. I am not aware of any method of stopping one tween while leaving the other playing on a single movieclip (or if they are each on the main stage).
That said, you can stop and start animations fairly easily. Below is an example of how to stop a motion tween where it is in playback, and then resume it from that point.
In the example, "myMovieClip" is the movie clip we're working with. We're going to leave the rest of the movieclips alone, as they'll keep playing on their own. I'm also assuming that myMovieClip is playing by default.
The following is in AS3. Place it on the Actions panel for your main stage (first frame if you have multiple frames.)
Also, ensure you have named your MovieClip. To do this, click the MovieClip on your stage in design mode, and then click Properties. There should be a text entry box towards the box. Write the name you want for your MovieClip there.
//Declare a boolean variable that determines whether or not the movieclip timeline is playing.
var ClipPlaying:Boolean = true;
//Add the mouse click event listener to the movie clip.
myMovieClip.addEventListener(MouseEvent.CLICK, StopOrStartClip);
//Declare the function for the above event listener.
function StopOrStartClip(evt:MouseEvent):void
{
//Switch statements are my personal favorites...they're more streamlined than if statements.
switch(ClipPlaying)
{
//If the clip is playing it, we stop it and set ClipPlaying to false.
case true:
myMovieClip.stop();
ClipPlaying = false;
break;
//If the clip is not playing, we start it and set ClipPlaying to true.
case false:
myMovieClip.play();
ClipPlaying = true;
break;
}
}
The most important functions to remember here are:
myMovieClip.stop();
This freezes your animation at its current position.
myMovieClip.play();
This resumes your animation playback from its current position.
When you use either, remember to replace "myMovieClip" with the name of your movie clip!
By the way, slightly unrelated, I highly recommend the book ActionScript 3.0 Game Programming University to learn how to create Flash games.
You wouldn't actually need 5 different event listeners, or functions, or variables; you could just make one function to handle it all:
stage.addEventListener(MouseEvent.CLICK, stageClick);
function stageClick(event:MouseEvent):void {
//I prefer "if" statements
if (event.target == myMovieClip1) stuff here;
else if (event.target == myMovieClip2) stuff here;
else if (event.target == myMovieClip3) stuff here;
else if (event.target == myMovieClip4) stuff here;
else if (event.target == myMovieClip5) stuff here;
}
I can add more details if needed, but this question was from three years ago so probably not.

Resources