Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[RELEASED] SoundManagerPro: Easy Game Music Plugin

Discussion in 'Assets and Asset Store' started by AntiLunchBox, Jun 12, 2013.

  1. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Are you playing these in an update function? Or immediately after one another? What you want to do will take a little extra coding but not much. So that PlaySFX function returns the AudioSource. You can simply do something that checks to see if the audiosource is still playing. For instance,

    AudioSource myAudio;

    void Update()
    {
    if(myAudio !== null !myAudio.isPlaying)
    myAudio = SoundManager.PlaySFX();
    }

    Something like that will play the sounds in succession.

    ALB
     
  2. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey eridani,

    I think a better option for you is to ignore the level loading algorithm by using: SoundManager.SetIgnoreLevelLoad(true)

    SMP will notice if the same SONG is playing, but it will not notice if an identical SoundConnection is playing, so it's trying to crossfade(which makes the volume go down). So, SetIgnoreLevelLoad will be the right thing for you to use when you start your menu.

    Then in your first menu scene, just use SoundManager.PlayConnection to manage the music on your own. Just make sure to use that in a Start() function, not Awake().

    You can turn on the level loading algorithm whenever you want later.

    Hope that helps,
    ALB
     
  3. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Ah,

    What's happening is that the SoundManager is set to persist across scenes, but the pooled objects are not. So when you go back to the game scene, the pooling starts over (it still works). Because you left the game scene, those pooled sfx objects got deleted. What you can do is set the SFX objects to DontDestroyOnLoad.

    For instance, when you are playing a sound you can do:

    DontDestroyOnLoad(SoundManager.PlaySFX().gameObject);

    Hope that helps,
    ALB
     
  4. sshepelevich

    sshepelevich

    Joined:
    Nov 21, 2013
    Posts:
    10
    Wait, but what I mean is that SFX game objects are not being deleted at all!!! So when I get to game scene for second time, I get huge amount of SFG objects over time. At the first time, maximum amount of SFX is 5. So the general problem is that they do remain at the scene.
    Image is attached.

    Thanks,
    Serge

    $unity-sound.jpg
     
  5. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Ah,

    So I did check and the SFX objects are meant to persist across scenes however SMP still reuses those SFX objects even if you change scenes. It continues to pool. So that shouldn't be happening. Maybe you are playing a lot more SFXs than you think? Try using PlayCappedSFX to cap your SFX at a certain amount and see what happens.

    ALB
     
  6. sshepelevich

    sshepelevich

    Joined:
    Nov 21, 2013
    Posts:
    10
    Well,

    In that case amount growing would be present at first time too. I will try play CappedSfx and will let you know, though I'm sure it wont help.
     
  7. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    sshepelevich,

    Another thing I noticed about the image you posted is that the SFXObjects are still active (inactive objects are a dark grey like the 'Menu' object you have there). Are you by any chance playing a looping sound? The objects will stay active if they are still playing. I'd imagine the audio file you are playing is still playing. What is the length of the file you are playing? What is the code you are using to call PlaySFX?

    ALB
     
  8. sshepelevich

    sshepelevich

    Joined:
    Nov 21, 2013
    Posts:
    10
    ALB,

    Sound is 0.335 sec length. I play it through SoundManager.PlaySFX(SoundManager.Load("short_throw_new"));

    So, here is the error description:

    1. I have a scene where the most used sound is throwing of snowball. So at the first time, maximum amount of SFX objects I can get is about 5. I see how they become active and then inactive, so I see that they're being reused.
    2. I hit exit to menu button. I still see those SFX objects at menu scene. So everything is working as expected for now.
    3. I hit play again button. At the game scene I see those 5 SFX objects, they're inactive.
    4. As I start throwing my snowballs and play sound, I see that inactive objects become active, but now they dont become inactive anymore, that's why new SFXs are spawned.

    So general question is why active objects dont become inactive for the second time?

    Serge
     
  9. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Okay,

    So this should be the same situation:

    1. Open up the demo scene
    2. Go to MusicScene1
    3. Hit the "Click Me!" button to play some SFX a few times.
    4. Go to MusicScene2
    5. Go back to MusicScene1
    6. Hit the "Click Me!" button to play some SFX a few times.

    I am seeing it work correctly in this case. When you go to the demo scene does it work fine? You should send me an example where I can repro it.

    ALB
     
  10. Bast-I

    Bast-I

    Joined:
    May 28, 2013
    Posts:
    18
    Hi ALB,

    I am considering buying your asset, but first, I want to know a few things. I watched some videos and had a look at the documentation but didn't find the things I was looking for, so I hope it's okay to ask in this forum:
    1. I guess something like playing an intro-bgm once, followed by a second, looping bgm is straight-forward, right? I am asking because in the videos it seemed to me as if for any given level, you only had the choice of selecting the playback behavior (playing continuously etc.) for all bgms of that level.
    2. I want to switch bgms after a certain event was triggered. But the switch should happen at a certain playback position of the bgm -- for example, at the 48 seconds mark. If that was not too clear: Imagine a looping bgm. Then the character collects an item which triggers the switch. The next time the bgm reaches the 48 seconds mark, it stops and a new bgm begins to play. How can that be achieved with your asset?

    Thank you

    Bast I
     
  11. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey Bast,

    Sure I'm open to answer any questions.

    1. Yes this is easy to do. There is a function called SoundManager.Play() that has an overload that runs any function once the song is finished. You can use this, or manually assign actions to: song end, song begin, finish crossfade in, or begin crossfade out. Using SoundManager.Play is simple for what you want to do though. The function that you put in can then call SoundManager.PlayConnection() or SoundManager.Play() for the second looping bgm.

    2. That can be accomplished with a little tweak in the SoundManager_Variables file. You just have to change the 'AudioSource currentSource' variable from private to public to be able to access the current bgm source playing [using SoundManager.Instance.currentSource]. You can then use that to check when the next 48 second mark happens. Then you can easily use SoundManager.PlayImmediately (ignore crossfade), SoundManager.Play (crossfade to new song), or SoundManager.PlayConnection(play a whole new playlist of songs)--whichever you want.

    Hope that helps,
    ALB
     
  12. Afroman

    Afroman

    Joined:
    Aug 17, 2013
    Posts:
    43
    I just bought sound manager pro. I'm wondering how would I use audio filters? I have gone through the documentation and can't seem to find a way to integrate it with sound manager.
     
  13. Bast-I

    Bast-I

    Joined:
    May 28, 2013
    Posts:
    18
    Thanks for your answers, ALB. Bought it a minute ago. Can't wait to try it. Bast I
     
  14. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey, this should be fixed now. It was a problem for webplayers with the new webplayer security system. Just had to add cross domain file. Should be good to go now! You don't have to update anything.

    ALB
     
  15. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey Afroman,

    You'll have to add it in code. So since all the SFX functions return the resulting audiosource, you can do something like this:

    Code (csharp):
    1.  
    2. AudioSource thisSource = SoundManager.PlaySFX(SoundManager.Load("Explosion1"));
    3. AudioEchoFilter echoFilter = thisSource.GetComponent<AudioEchoFilter>();
    4. if(echoFilter == null)
    5.     echoFilter = thisSource.gameObject.AddComponent<AudioEchoFilter>();
    6. //then modify echo filter variables as you like.
    7.  
    I'm working on an easier way to add them in the editor.
    ALB
     
  16. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Version 2.7.3 is live!

    This is only part of my upcoming update, but I figured I'd post what is currently fully fixed. In this update we have a fix to the Undo warnings in 4.3, some small Unity 4.3 bug fixes, and some miscellaneous editor fixes. More to come in the upcoming days.

    ALB
     
  17. eridani

    eridani

    Joined:
    Aug 30, 2012
    Posts:
    655
    I've been trying to reproduce it myself...seems to happen very infrequently and completely randomly. I'll save the project file and end it to you the next time I see it. Thanks!
     
  18. URZqqq

    URZqqq

    Joined:
    Dec 9, 2013
    Posts:
    4
    Hello,

    I just tested your plugin, and so far it works as expected, and it's easy to use :)
    I have a question thought, and google didn't help me.

    In my game, there is a distinction between music and ambient sound. A music is well ... a music, and I can use your SoundManager to handle it for me. An ambient sound looks very similar to music: same length, needs to be played in a loop mode, scene dependant. But to handle it, I can't use the music system, since there seems to have no "mode" in which I can play two musics simultaneously.

    I could treat those ambient sounds as SFX, and write a script using PlaySFXLoop(...) and StopSFX() according to the current scene name, but it seems a little bit tedious... Is there a better way to achieve what I want to do?

    I hope it was clear, and thanks :)
     
  19. eridani

    eridani

    Joined:
    Aug 30, 2012
    Posts:
    655
    Also, another intermittent issue I have seen... if I pause my game by setting the timescale to zero, then unpause it, sometimes every sound effect that's loaded will be played all at once at the same time. This doesn't happen all the time.
     
  20. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    You actually have that correct but you would use StopSFXObject on the gameobject that PlaySFXLoop returns. I may add that as a feature pretty soon, though. Lately, I've been asked about it quite a bit.

    ALB
     
  21. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Before and after you set the timescale, you can use SoundManager.Pause/UnPause/PauseToggle

    ALB
     
  22. HannesB

    HannesB

    Joined:
    Oct 29, 2012
    Posts:
    10
    hi,

    I am creating sound connections by assigning an MP3 file and also select my main menu scene where it should be played in the background.

    When building the project, i am getting this errors:

    An asset is marked as dont save, but is included in the build:
    Asset: 'Assets/Game/Sounds/Title_Loop.mp3'
    UnityEditor.HostView:OnGUI()

    Building - Failed to write file: sharedassets0.assets
    UnityEditor.HostView:OnGUI()

    Error building Player: Couldn't build player because of unsupported data on target platform.

    The assigned sound file is in .mp3 Format, Playing it in the unity editor is no problem.
    (It was .wav Format, which was not working too, so i created a mp3 from it but this did not solve the problem)

    This is simple to reproduce - removing the sound connection solved the problem so i am quite sure the problem is caused by SoundManager Pro. Can you please test this to reproduce the problem?

    best regards,
    Hannes
     
  23. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Have you tried deleting the audio file and re-adding it to the project? I've gotten that error before a few random times(in projects without SMP) and I did a search on the forums for the answer and that was it. It worked for me.

    Let me know if that fixes it.

    ALB
     
  24. Hesham

    Hesham

    Joined:
    May 29, 2008
    Posts:
    147
    I use the following command to loop an FX on the same object, the effect itself play once and doesn't loop:

    Code (csharp):
    1.  
    2. SoundManager.PlaySFXLoop(gameObject,SoundManager.Load("greenbeam"));
    3.  

    Additionally, if I start a level other than the first one that has the SMP prefab, none of the sounds play. Is it possible to have reference the main prefab?
     
  25. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    Hi ALB,

    I have the same issue as eridani below, though a bit worse.

    What triggers "The cross duration is longer than the track length!" errors is when we play a sound connection, but the current playing sound connection only has a couple of seconds left.

    E.g., the default cross duration is 5 seconds. If I play the same sound connection with less than 5 seconds remaining in the current song, the error appears.

    Actually, sometimes it appears, at other times it seems to go into an infinite loop, hanging Unity (4.2.2f1). Not sure where exactly, as I can't pinpoint where it dies.

    Chris


     
  26. URZqqq

    URZqqq

    Joined:
    Dec 9, 2013
    Posts:
    4
    Hi !

    I had the same issue, and found a workaround

    Code (csharp):
    1.  
    2.  AudioClip audioClip = SoundManager.Load(SFXName);
    3. //last parameter is "loop"
    4.  SoundManager.PlaySFX(gameObject, audioClip, true);
    5.  
    @ ALB
    I'm currently working on a sound option menu, with an interface designed with NGUI.
    What I'm trying to do is to set the music's volume with the help of a slider (I also want later to set the SFX's volume with another slider).
    My problem is that none of those work:

    Code (csharp):
    1.  
    2. void OnSliderChangeMusic()
    3. {
    4.     //doesn't work
    5.     SoundManager.Instance.maxMusicVolume = musicSlider.sliderValue
    6.     //doesn't work
    7.     SoundManager.SetVolumeMusic(musicSlider.sliderValue);  
    8. }
    9.  
    What am I missing ?

    Thanks

    EDIT: found it myself. What I'm doing now is:
    Code (csharp):
    1.  
    2. void OnSliderChangeMusic()
    3. {
    4.         SoundManager.SetVolume(1f);
    5.         SoundManager.SetVolumeMusic(musicSlider.sliderValue);
    6. }    
    7.  
    But I don't know why it wasn't working before, since I believe I didn't touch the global volume before :p
     
    Last edited: Dec 12, 2013
  27. Gavin1969

    Gavin1969

    Joined:
    Apr 30, 2013
    Posts:
    5
    Hi

    I'm just implementing SMP for the first time and planned to be able to resume playback of a SoundConnection via a callback when a Play request to an alternate AudioClip was played/finished. I assumed the runOnEndFunction param would be the place for such a callback to go.

    As you said in a post from a few weeks ago ->

    "I remember somebody else asking something similar. Keep in mind that OnSongEnd applies to the song your are playing with that function, not to the song that was playing previously. You'll have to assign OnSongEnd manually before calling SoundManager.Play if you want it to be like that."

    However, the behaviour I see in the SoundManagerProDemoScene seems to be that when the track being faded out ends the callback (to change a button colour in the example) for the new track is invoked. This doesn't seem to be very useful, unless I'm missing something?

    I'm using Unity 4.3.1, if that could be a factor?
    SMP is the latest version on the Store.

    In a vague attempt to be clear - I'd like a callback to be invoked when the track I Play (supplying a callback) ends, not when the track being faded out to enable the new one to play ends.

    Hope you can point me in the right direction regarding this issue,
    Thanks!

    Gavin
     
  28. eridani

    eridani

    Joined:
    Aug 30, 2012
    Posts:
    655
    I have a question related to playing sounds for the first time in a game... does SoundManager not pre-load audio into memory, so that the first time a sound is called by the game is when it is actually instantiated and then saved into an audio pool?

    Isn't it preferred that all the audio be pre-loaded in advance so that there is never instantiation happening during gameplay?

    For example, I have one level in my game where the player is basically dropped into a bullet hell where about 8 new attack and damage sounds are played at once almost simultaneously for the first time, and the gameplay stutters when this happens, I'm assuming because numerous audio is being instantiated?

    Please confirm if my understanding of SoundManager is correct, otherwise I'll have to investigate other causes of the gameplay stutter. Thanks!
     
  29. jhample

    jhample

    Joined:
    Jul 7, 2012
    Posts:
    47
    I have a question about playing a random song. I made a connection that has 5 songs in it set to a level. A song is randomly selected at the start of the level (which is what I want). However after the song is over it goes to the next song. Is there any "repeat 1" option?
     
  30. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey Hesham,

    Thanks for pointing this out. I actually found the bug. Will post the fix in a couple minutes.

    ALB
     
  31. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    K I've been trying to reproduce this for days, but I think I finally found out the problem. This only happens when you are using a 1 track SoundConnection and re-try to play that same SoundConnection once it's crossing between the same track (a very specific situation). I have the fix, will be posting soon. Thanks guys for helping with the clarification! Took a really long time to identify.

    ALB
     
  32. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey Urzqqq,

    The PlaySFXLoop bug should be fixed now. That workaround works but its not exactly the same as PlaySFXLoop.

    As for the set volume, you should only have to use SoundManager.SetVolumeMusic(musicSlider.sliderValue); You don't have to set maxMusicVolume before calling that.

    -ALB
     
  33. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey eridani, in the SFX video on youtube you can find some info on various memory management options with SMP. For you situation, I would suggest putting those bullet sounds on the SoundManager. Then you should use SoundManager.Load("string clip name") whenever you are playing a SFX function. The load function will always check the SoundManager prefab first. Because the bullet sounds are on the SoundManager, it is indeed already preloaded into memory and loaded when your app first opens. I would also suggest using PlayCappedSFX for bullet sounds so that the number of bullet sounds at once isn't overwhelming. You don't need to play 100 bullet sounds at once when playing ~10 would have the same effect. You can even add the bullet sounds to a SFXGroup, and have an specific cap value for only bullet sounds.

    ALB
     
  34. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey jhample,

    There are a couple different ways to do this. I can add a repeat 1 option, but I'll give you a workaround in the meantime.

    Option 1: Choose a clip at random (however you want to do that), and use SoundManager.Play(audioClip, true);
    This will play that random clip as a single song SoundConnection that loops.

    Option 2: Add all 5 clips as SFX, and put them in their own SFX group. Use SoundManager.Play(SoundManager.LoadFromGroup("thisgroup"), true);
    This is similar to option 1, but we're cheating by using the SFX functionality to randomly load a clip from a group.

    Option 3: Make 5 custom soundconnections (song1, song2, song3, song4, song5) and set them all to have 1 song with ContinousPlayThrough. THEN, in a Start() function, call SoundManager.PlayConnection("song"+Random.Range(1,6).ToString());
    This will play one of those custom soundconnections randomly.

    Hope that helps,
    ALB
     
  35. puzzlekings

    puzzlekings

    Joined:
    Sep 6, 2012
    Posts:
    404
    Hi ALB,

    Thanks for your response. Sorry for the delay in responding, as I need to try SMPro which I did today - very nice and easy to integrate :)

    Regarding the Car Engine Sound, what I am after is a simple component where you can set the RPM and it automatically crossfades - much like in the FMOD Unity demo or as in the Unity Car Tutorial. The issue is that this needs to interact with the SMPro components that play Capped SFX and handle pooling etc.

    I was wondering whether you might consider this type of component in the future?

    cheers,

    N
     
  36. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Ya sure, that actually wouldn't be that hard. In the SoundManager_Internal.cs file there are a couple functions that are private named Crossin, Crossout, Crossfade, Crossoutall. You can search for their names for how they're used. You basically specify the 2 audio sources and the crossfade duration in an object. Then you should be able to crossfade 2 sfx objects in a function using that. I would have to do further testing with pooling, but I'll def take a shot at incorporating that. In the meantime, you can mess with that if you want.

    ALB
     
  37. Alanj2007

    Alanj2007

    Joined:
    Aug 22, 2013
    Posts:
    17
    So, I bought this plugin and it was amazing. I call the function with C# and it works perfectly but in this cutscene script, there is a lot of yield WaitForSeconds. You know that it's complicated to make in C# so I suggest to call it from JS but how? I know there is a possible way to do this.

    This is a documentation of SoundManagerPro (Author said this is compitable in JS so it's possible)

    http://antilunchbox.com/soundmanagerpro/soundmanagerpro-documentation/
     
  38. one3dGames

    one3dGames

    Joined:
    Oct 31, 2013
    Posts:
    3
    Hello There,

    I have been trying to implement SoundManagerPro into a iOS Game but always get the same Error:

    An asset is marked as dont save, but is included in the build:
    Asset: 'Assets/SoundManagerPro/Demo/DemoSounds/DJ Etch - Carve Him Up.mp3'
    UnityEditor.HostView:OnGUI()

    There is nothing else in the assets folder then the SMP files.
    Any Idea?
    If you do nothing at all to the SMP in the SoundManagerProDemoScene it will mount to the iPad!
    But as soon as you add a song it will give the Error abouve.

    Thanks for any help
     
  39. Alanj2007

    Alanj2007

    Joined:
    Aug 22, 2013
    Posts:
    17
    Hey, just change a little bit preference on the music > Apply > Change it back to default > Apply
    then error should be gone

    I just do this
    Set it to 3D sound > Apply > Set it to 2D sound > Apply

    P.S Also can you answer my question above? Do you know how to do that?
     
    Last edited: Dec 27, 2013
  40. one3dGames

    one3dGames

    Joined:
    Oct 31, 2013
    Posts:
    3
    I do not code , I'm using PlayMaker to do the coding for me. There is not much I could help you out with!
    Thank you Alanj2007
     
  41. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey Alan,

    Sorry, I'm a little late, was away for Christmas. I'm not quite sure what you are asking but you can use SMP with javascript. There is nothing specifically in there that would make you need to use Coroutines, but for javascript you don't have to use StartCoroutine.

    "When using JavaScript it is not necessary to use StartCoroutine, the compiler will do this for you. When writing C# code you must call StartCoroutine."

    If you could tell me a bit more about your situation, I could help you further.

    -ALB
     
  42. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey one3dGames,

    I just answered this in your email to me, but I'll post the answer on here as well for other people:

    -ALB
     
  43. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Oh, looks like you answered it for me. Thanks Alan!
     
  44. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Ah Alanj,

    I think I know what you want to know now. In order to call from JS, you need to go to Window > AntiLunchBox > Setup For JS.

    This will move the scripts to the necessary folders so that you can call the functions from JS.

    -ALB
     
  45. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Hey rocki,

    Just wanted to give you an update. I haven't forgot about this! So I was able to create an audio system for Daikon Forge GUI since there isn't one currently in place. I'm getting it cleared with them before submitting the update. Not only will you be able to use audio with their gui system now, but it'll respect all your SMP settings.

    ALB
     
  46. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    DF-GUI integration is officially live in version 2.8.0. You can update it! It includes a full audio system for DF-GUI so it should be easy to do audio now for it.

    ALB
     
  47. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Changelog in 2.8.0:
    • DF-GUI integration included along with audio system
    • All other integrations are updated to reflect latest releases
     
  48. MalboM

    MalboM

    Joined:
    Apr 29, 2013
    Posts:
    66
    Does it work well on iOS?
     
  49. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Sure it does ;)
     
  50. AntiLunchBox

    AntiLunchBox

    Joined:
    Jun 6, 2013
    Posts:
    470
    Yup, as BTStone said, it works on iOS. In fact, it was originally designed to be efficient for mobile.

    -ALB