Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
877 stars 573 forks source link

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

Closed ptrbrynt closed 2 months ago

ptrbrynt commented 5 years ago

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!

github-actions[bot] commented 4 years ago

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.

RichardoC commented 3 years ago

Did this end up getting implemented?

GibreelAbdullah commented 3 years ago

This would be so helpful

github-actions[bot] commented 10 months ago

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.

RichardoC commented 10 months ago

/remove lifecycle stale

RichardoC commented 10 months ago

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

changcw83 commented 3 months ago

ya would be great to have panning

Larpoux commented 3 months ago

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

changcw83 commented 3 months ago

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?

Larpoux commented 3 months ago

@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  git@github.com: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 :

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.

changcw83 commented 3 months ago

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

Larpoux commented 3 months ago

Yeah! πŸ‘ You did the most difficult step. Now Everything will be easy : Here are the layers :

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 commented 3 months ago

The dart implementation of setSpeed() is in :

changcw83 commented 3 months ago

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

changcw83 commented 2 months ago

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

Larpoux commented 2 months ago

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

changcw83 commented 2 months ago

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

Larpoux commented 2 months ago

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.

changcw83 commented 2 months ago

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.

let panPosition = AVAudio3DPoint(x: 1.0, y: 0.0, z: 0.0)
environmentNode.listenerPosition = panPosition

Step 5: Play the Audio

playerNode.play()

Example Explanation:

Notes:

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

changcw83 commented 2 months ago

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.

Larpoux commented 2 months ago

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

Larpoux commented 2 months ago

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.

changcw83 commented 2 months ago

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

Larpoux commented 2 months ago

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

changcw83 commented 2 months ago

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 commented 2 months ago

Think this clip should be a clearer example

Larpoux commented 2 months ago

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

changcw83 commented 2 months ago

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):

Larpoux commented 2 months ago

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

changcw83 commented 2 months ago

have done so, first time in my life :)

Larpoux commented 2 months ago

You probably modified also flutter_sound_core. Don’t forget to do another pull request for this repo

changcw83 commented 2 months ago

ok done too for flutter_sound_core and flutter_sound_web

Larpoux commented 2 months ago

This is great. Congratulations πŸ₯‡ . I am going to look your pull request. If/when everything will seem good I will merge your pr in the master branch. Then I will do some very quick tests and I will release a new flutter sound version.

there is also the problem of the documentation: actually it is in bad shape. Some new features are not included in the 9.x documentation. I am busy working on a new documentation for 10.0 . You can choose to include your new feature in the 9.x documentation, or wait the 10.0 . I vote for the former: 9.x will be maintained during a foreseeable future. Probably during one or two years.

changcw83 commented 2 months ago

fixed some errors, trusted chatgpt too much.

On Sun, 18 Aug 2024 at 22:25, Larpoux @.***> wrote:

This is great. Congratulations πŸ₯‡ . I am going to look your pull request. If/when everything will seem good I will merge your pr in the master branch. Then I will do some very quick tests and I will release a new flutter sound version.

there is also the problem of the documentation: actually it is in bad shape. Some new features are not included in the 9.x documentation. I am busy working on a new documentation for 10.0 . You can choose to include your new feature in the 9.x documentation, or wait the 10.0 . I vote for the former: 9.x will be maintained during a foreseeable future. Probably during one or two years.

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

changcw83 commented 2 months ago

Apologise for the buggy version, figured out the fix myself, tested on ios simulator and my android phone

Larpoux commented 2 months ago

Apologise for the buggy version, figured out the fix myself, tested on ios simulator and my android phone

No problem, Chang. I appreciate this work that you do on Flutter Sound to let it be better. Actually you are the only developer on Flutter Sound, except me. Congratulations. We really need people to work on free projects. I am very grateful for your contribution.

Larpoux commented 2 months ago

Flutter Sound 9.11.2 is released.

9.11.2

9.11.0