flutter_sound icon indicating copy to clipboard operation
flutter_sound copied to clipboard

Feature Request: Audio panning (left/right balance adjustment)

Open ptrbrynt opened this issue 6 years ago • 6 comments

I'd love to have a way to control the left/right balance of the currently playing audio. It looks like the iOS and Android audio player APIs both support this so I guess it's possible with Flutter!

ptrbrynt avatar Apr 26 '19 23:04 ptrbrynt

This issue is stale because it has been open 90 days with no activity. Leave a comment or this will be closed in 7 days.

github-actions[bot] avatar Jan 01 '20 00:01 github-actions[bot]

Did this end up getting implemented?

RichardoC avatar Mar 17 '21 00:03 RichardoC

This would be so helpful

GibreelAbdullah avatar May 08 '21 07:05 GibreelAbdullah

This issue is stale because it has been open 90 days with no activity. Leave a comment or this will be closed in 7 days.

github-actions[bot] avatar Dec 25 '23 01:12 github-actions[bot]

/remove lifecycle stale

RichardoC avatar Dec 25 '23 14:12 RichardoC

Can we reopen this? Still keen to have this functionality Thanks!

RichardoC avatar Jan 03 '24 17:01 RichardoC

ya would be great to have panning

changcw83 avatar Aug 15 '24 10:08 changcw83

Yes. Sure. This is definitely something that is easy to implement and that is badly missing. Actually, I am busy working on Flutter Sound V10.0. I can't implement new features in the 9.x, if I really want to release one day 10.0. So I only do maintenance on the 9.x (fix bugs).

When 10.0 will be released, we will see what we will want to do on 9.x. If someone can do a PR on 9.x, it would be wonderful.

I added this request in the Kanban table

Larpoux avatar Aug 15 '24 10:08 Larpoux

If there's ever this feature would it be possible to control the left and right volume of the audio and broadcast to both left and right channel?

changcw83 avatar Aug 16 '24 00:08 changcw83

@changcw83 : thank you so much for your proposition to contribute to Flutter Sound project. Flutter Sound 9.x has a complicated architecture for legacy reasons. Flutter Sound 10.0 will have a much simpler architecture and it will be easier to contribute to it.

I think that the first step for you is to have a working dev. You can have a look to the dev documentation but this page is very outdated.

I suggest that you do :

git clone --recursive  [email protected]:Canardoux/flutter_sound.git
cd flutter_sound
bin/reldev.sh DEV

and then try to execute the example under Android Studio or Visual Studio Code (I use Android Studio). btw :

  • you will need a mac for your dev, because of iOS.
  • you need some command line utilities like gsed to execute bin/reldev.sh DEV

Having a running dev environment is probably the the most painful step, but this is a required step. When you will have a dev environment working, it will be simpler. I will help you.

Larpoux avatar Aug 16 '24 07:08 Larpoux

Got the example to run, ready to develop the new feature, do guide me how, thanks

changcw83 avatar Aug 16 '24 13:08 changcw83

Yeah! 👍 You did the most difficult step. Now Everything will be easy : Here are the layers :

  • The examples (on top)
  • The dart code (used by the examples)
  • The Native code (which is a simple bridge between dart and the Flutter Sound Core
  • The flutter sound core which does everything. There is 3 core modules : one for Android, one for iOSS and one for web.

You can operate on those 4 layers in the order that you prefer. Top Down, or Bottom up. (or on the 4 layers at the same time!)

1 - The examples You want to create a new example. The example is a driver which calls all the elementary examples. You will add in this dart file an import to your example. Then you will create your example as a new dir inside https://github.com/Canardoux/flutter_sound/tree/master/flutter_sound/example/lib. You probably want to copy a very simple example witch has already a cursor, like Volume Control

2- The dart code You probably want to add a new verb setPanner() or something like that. This verb will call a new procedure inside flutter_sound_platform_interface/flutter_sound_player_platform_interface.dart and flutter_sound_platform_interface/method_channel_flutter_Sound_recorder.dart

3- The native code I suggest that you don't work at the same time on the three platforms (Android, iOS and Web). Let us say that you choose iOS. There are many files inside flutter_sound/flutter_sound/ios/Classes but they are just a bridge to FlutterSoundCore. You will modify FlutterSoundPlayerManager.mm and FlutterSoundPlayer.mm. You will just call a new verb inside FlutterSoundCore

4- flutter_sound_core You will add your new verb inside flutter_sound_core/ios//Classes/FlautoPlayer.mm

It should not be too much difficult. Probably you can duplicate the setVolume code on the 4 layers and modify it for your new thing.

Of course, don't hesitate to ask me if any question.. I will be very glad to help you.

Larpoux avatar Aug 16 '24 16:08 Larpoux

The dart implementation of setSpeed() is in :

  • flutter_sound/lib/public/flutter_sound_player.dart (The API as seen by the app)
  • flutter_sound_platform_interface/lib/flutter_sound_player_platform_interface.dart (the declaration)
  • flutter_sound_platform_interface/lib/method_channel_flutter_sound_player.dart (the implementation for iOS and Android)
  • flutter_sound_web/lib/flutter_sound_player_web.dart (the implementation for Web)

Larpoux avatar Aug 17 '24 06:08 Larpoux

I will likely just overload the setvolume to handle two parameters left and right.

changcw83 avatar Aug 17 '24 13:08 changcw83

Think I sort of figured out android's implementation, but for ios, think I'm stuck seems not so direct to set left and right volume

changcw83 avatar Aug 18 '24 08:08 changcw83

There are 3 platforms : iOS, Android and Web. Don't forget Web.

Larpoux avatar Aug 18 '24 08:08 Larpoux

Ok, but can you give some suggestions on ios? Seems lacking the functionality to set left and right volume

changcw83 avatar Aug 18 '24 08:08 changcw83

I don't have any idea of what it can be achieved on iOS. The only thing I am sure, is that it will be simple to do, because setting the balance on a mediaPlayer is a basic feature.

Larpoux avatar Aug 18 '24 08:08 Larpoux

Got the following from chatgpt, shall try it

To pan volume in iOS, you can use the AVAudioEngine class along with AVAudioPlayerNode and AVAudioEnvironmentNode. Here's a basic example to demonstrate how to implement panning in your iOS app using Swift:

Step 1: Import Required Modules

import AVFoundation

Step 2: Setup the AVAudioEngine

let audioEngine = AVAudioEngine()
let playerNode = AVAudioPlayerNode()
let environmentNode = AVAudioEnvironmentNode()

audioEngine.attach(playerNode)
audioEngine.attach(environmentNode)

audioEngine.connect(playerNode, to: environmentNode, format: nil)
audioEngine.connect(environmentNode, to: audioEngine.mainMixerNode, format: nil)

do {
    try audioEngine.start()
} catch {
    print("Audio Engine couldn't start: \(error.localizedDescription)")
}

Step 3: Load the Audio File

if let fileURL = Bundle.main.url(forResource: "your_audio_file", withExtension: "mp3") {
    do {
        let audioFile = try AVAudioFile(forReading: fileURL)
        playerNode.scheduleFile(audioFile, at: nil, completionHandler: nil)
    } catch {
        print("Couldn't load the audio file: \(error.localizedDescription)")
    }
}

Step 4: Set the Panning

You can control the panning by setting the position of the AVAudio3DPoint object.

  • The x coordinate controls the left/right panning.
  • The y coordinate controls the up/down panning.
  • The z coordinate controls the front/back distance.
let panPosition = AVAudio3DPoint(x: 1.0, y: 0.0, z: 0.0)
environmentNode.listenerPosition = panPosition

Step 5: Play the Audio

playerNode.play()

Example Explanation:

  • AVAudioPlayerNode is used to play the audio.
  • AVAudioEnvironmentNode is responsible for controlling the spatial effects, such as panning.
  • By adjusting the x value in AVAudio3DPoint, you can control the left/right panning effect.

Notes:

  • The x coordinate value ranges from -1.0 (full left) to 1.0 (full right), with 0.0 being the center.
  • You need to ensure that the audio engine is running before starting playback.

This approach gives you a flexible way to pan audio in your iOS application.

changcw83 avatar Aug 18 '24 08:08 changcw83

Another attempt in objective-c seems easier

To pan audio in iOS using Objective-C, you can use the AVAudioPlayer class, which provides control over audio playback, including panning. Here's how you can achieve panning:

  1. Import the necessary framework:

    #import <AVFoundation/AVFoundation.h>
    
  2. Set up your audio player:

    Load your audio file into an AVAudioPlayer instance.

    NSString *path = [[NSBundle mainBundle] pathForResource:@"your-audio-file" ofType:@"mp3"];
    NSURL *soundURL = [NSURL fileURLWithPath:path];
    
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
    
  3. Set the pan property:

    The pan property of AVAudioPlayer controls the stereo pan position of the audio. The range is from -1.0 (full left) to 1.0 (full right), with 0.0 being the center.

    audioPlayer.pan = -1.0; // Full left
    // or
    audioPlayer.pan = 1.0; // Full right
    // or
    audioPlayer.pan = 0.0; // Center (default)
    
  4. Play the audio:

    Finally, start playing the audio.

    [audioPlayer play];
    

This will allow you to control the panning of your audio in your iOS application. If you need more advanced audio handling, you might also consider using the AVAudioEngine framework, which provides more granular control over audio processing.

changcw83 avatar Aug 18 '24 08:08 changcw83

The AVAuidioPlayer in iOS is in flutter_sound_core/ios/Classes/FlautoPlayerEngine

Larpoux avatar Aug 18 '24 08:08 Larpoux

You will have to add a virtual function in the interface and do something for the other classes implementing this virtual function. The other classes are mainly to support PlayFromStream. In a first step, you can do an exception Not implemented for Streams.

Larpoux avatar Aug 18 '24 09:08 Larpoux

Now I need to host an audio with separate left and right channels to put in example

changcw83 avatar Aug 18 '24 12:08 changcw83

I guess that all the examples under https://tau.canardoux.xyz/danku/extract/ (for example https://tau.canardoux.xyz/danku/extract/05.mp3) are stereo. If you want to put a new example on this host, just give it to me

Larpoux avatar Aug 18 '24 12:08 Larpoux

Ok, no problem easier to use existing ones, I try to get the example to work.

On Sun, 18 Aug 2024 at 20:24, Larpoux @.***> wrote:

I guess that all the examples under https://tau.canardoux.xyz/danku/extract/ (for example https://tau.canardoux.xyz/danku/extract/05.mp3) are stereo. If you want to put a new example on this host, just give it to me

— Reply to this email directly, view it on GitHub https://github.com/Canardoux/flutter_sound/issues/77#issuecomment-2295243353, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA6OPL2D5ER5473REWTRKTDZSCG7NAVCNFSM4HI222J2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMRZGUZDIMZTGUZQ . You are receiving this because you were mentioned.Message ID: @.***>

changcw83 avatar Aug 18 '24 12:08 changcw83

Think this clip should be a clearer example

changcw83 avatar Aug 18 '24 12:08 changcw83

https://tau.canardoux.xyz/danku/extract/leftright.mp3 is now on Canardoux host

Larpoux avatar Aug 18 '24 12:08 Larpoux

What do I have to do? I added setVolumePan based on setVolume, finding all occurrences and mimicing it

E/flutter (10299): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method setVolumePan on channel xyz.canardoux.flutter_sound_player) E/flutter (10299): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332) E/flutter (10299): E/flutter (10299): #1 MethodChannelFlutterSoundPlayer.invokeMethod (package:flutter_sound_platform_interface/method_channel_flutter_sound_player.dart:139) E/flutter (10299): E/flutter (10299): #2 FlutterSoundPlayer._setVolumePan (package:flutter_sound/public/flutter_sound_player.dart:1306) E/flutter (10299): E/flutter (10299): #3 FlutterSoundPlayer.setVolumePan. (package:flutter_sound/public/flutter_sound_player.dart:1289) E/flutter (10299): E/flutter (10299): #4 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:33) E/flutter (10299): E/flutter (10299): #5 FlutterSoundPlayer.setVolumePan (package:flutter_sound/public/flutter_sound_player.dart:1288) E/flutter (10299): E/flutter (10299): #6 _VolumePanControlState.setVolume1 (package:example/volumepan_control/volumepan_control.dart:108) E/flutter (10299): E/flutter (10299):

changcw83 avatar Aug 18 '24 13:08 changcw83

When you will be ready, you may do a Pull Request. Did you fork the repo ?

Larpoux avatar Aug 18 '24 13:08 Larpoux

have done so, first time in my life :)

changcw83 avatar Aug 18 '24 13:08 changcw83