SKKbySSK / coast_audio

Real-Time audio processing library written in Dart.
MIT License
89 stars 11 forks source link

The method 'setString' isn't defined for the class 'Array<Char>'. #25

Closed MaayanBogin closed 3 months ago

MaayanBogin commented 4 months ago

I'm having an issue with import flutter_coast_audio_miniaudio.

I'm using FlutterFlow (Yes yes I know) and after scouring the docs and lib files I ended up with this

Future<double> getAverageFrequency(String filePath) async {
  // Read audio data from the file
  final memory = Memory();
  final audioData = await readAudioFile(filePath, memory);

  // Perform FFT on the audio data
  final fft = FFT(audioData.length);
  final complexArray = fft.realFft(audioData);

  // Calculate the power spectrum
  final powerSpectrum = complexArray.map((c) => c.abs() * c.abs()).toList();

  // Find the maximum power in the spectrum
  Float64x2 maxPower = Float64x2.zero();
  int maxPowerIndex = 0;
  for (int i = 0; i < powerSpectrum.length; i++) {
    if (powerSpectrum[i].x > maxPower.x) {
      maxPower = powerSpectrum[i];
      maxPowerIndex = i;
    }
  }

  // Calculate the frequency corresponding to the maximum power index
  // Assuming you know the sample rate from the ID3 tag or other source
  final sampleRate = 48000;
  final maxFrequency = maxPowerIndex * (sampleRate / 2) / powerSpectrum.length;

  //memory.zeroMemory();
  return maxFrequency;
}

Future<List<double>> readAudioFile(String filePath, Memory memory) async {
  // Open the audio file
  final file = File(filePath);

  try {
    // Create an AudioFileDataSource
    final dataSource = AudioFileDataSource(file: file, mode: FileMode.read);

    // Determine the output format (assuming you know the format)
    final outputFormat =
        AudioFormat(sampleRate: 44100, channels: 1); // Adjust as needed

    // Create a buffer size
    final bufferSize = 4096;

    // Use ffi to allocate memory for the buffer
    final pBuffer = memory.allocate<ffi.Uint8>(bufferSize);

    // Create a MabAudioDecoder
    final decoder =
        MabAudioDecoder(dataSource: dataSource, outputFormat: outputFormat);

    final audioData = <double>[];

    // Decode audio data in chunks
    while (true) {
      final decodeResult = await decoder.decode(
        destination: AudioBuffer(
          pBuffer: pBuffer,
          sizeInBytes: bufferSize,
          sizeInFrames: bufferSize ~/ outputFormat.channels,
          format: outputFormat,
          memory: memory, // Pass the memory instance
        ),
      );

      // Check if decoding is finished
      if (decodeResult.isEnd) {
        break;
      }

      // Convert the decoded data in memory to a Dart List<double>
      for (var i = 0; i < decodeResult.frames * outputFormat.channels; i++) {
        final byte = pBuffer.elementAt(i).value;
        audioData.add(byte.toDouble());
      }
    }

    // Dispose decoder and data source
    decoder.dispose();
    dataSource.dispose();

    // Free memory
    calloc.free(pBuffer.cast<ffi.Void>());

    return audioData;
  } finally {
    // Dispose resources
    await file.delete();
  }
}

Finally I have code that is supposed to work but now I keep getting this error, possible id rather not change the lib files

ffi :^2.0.1 is the version I'm using

/opt/.pub-cache/hosted/pub.dev/coast_audio_miniaudio-0.0.4/lib/src/ma_bridge/device_info/aaudio_device_info.dart:26:31: Error: The method 'setString' isn't defined for the class 'Array<Char>'.
 - 'Array' is from 'dart:ffi'.
 - 'Char' is from 'dart:ffi'.
Try correcting the name to the name of an existing method, or defining a method named 'setString'.
    info.pDeviceInfo.ref.name.setString(name);
                              ^^^^^^^^^
/opt/.pub-cache/hosted/pub.dev/coast_audio_miniaudio-0.0.4/lib/src/ma_bridge/device_info/core_audio_device_info.dart:25:39: Error: The method 'setString' isn't defined for the class 'Array<Char>'.
 - 'Array' is from 'dart:ffi'.
 - 'Char' is from 'dart:ffi'.
Try correcting the name to the name of an existing method, or defining a method named 'setString'.
    info.pDeviceInfo.ref.id.coreaudio.setString(id);
                                      ^^^^^^^^^
/opt/.pub-cache/hosted/pub.dev/coast_audio_miniaudio-0.0.4/lib/src/ma_bridge/device_info/core_audio_device_info.dart:26:31: Error: The method 'setString' isn't defined for the class 'Array<Char>'.
 - 'Array' is from 'dart:ffi'.
 - 'Char' is from 'dart:ffi'.
Try correcting the name to the name of an existing method, or defining a method named 'setString'.
    info.pDeviceInfo.ref.name.setString(name);
                              ^^^^^^^^^
/opt/.pub-cache/hosted/pub.dev/coast_audio_miniaudio-0.0.4/lib/src/ma_bridge/device_info/mab_device_info.dart:31:43: Error: The method 'getString' isn't defined for the class 'Array<Char>'.
 - 'Array' is from 'dart:ffi'.
 - 'Char' is from 'dart:ffi'.
Try correcting the name to the name of an existing method, or defining a method named 'getString'.
  String get name => pDeviceInfo.ref.name.getString(256);
                                          ^^^^^^^^^
/opt/.pub-cache/hosted/pub.dev/coast_audio_miniaudio-0.0.4/lib/src/ma_bridge/device_info/opensl_device_info.dart:26:31: Error: The method 'setString' isn't defined for the class 'Array<Char>'.
 - 'Array' is from 'dart:ffi'.
 - 'Char' is from 'dart:ffi'.
Try correcting the name to the name of an existing method, or defining a method named 'setString'.
    info.pDeviceInfo.ref.name.setString(name); I get this error though

Thanks in advance hope someone helps me solve thissss!!!<3

SKKbySSK commented 4 months ago

@MaayanBogin Thanks for reporting issue. It looks like the version 0.0.5 of coast_audio introduced this breaking changes.

If you are not going to use the WavAudioDecoder class, you can downgrade your coast_audio dependency to 0.0.4 to fix the problem.

MaayanBogin commented 4 months ago

@SKKbySSK Thanks for the quick response! I'm only importing flutter_coast_audio_miniaudio: ^0.0.4, is there a version that is depended on a older version of coast_audio?

Edit: Tried 0.03 and it didn't work, Is there a workaround from changing the pubspace.yaml?

MaayanBogin commented 4 months ago

@SKKbySSK

Hello again! Hate to bug about this again but I cant seem to get it to work, Also it seems that flutter_coast_audio_miniaudio 0.0.4 is already dependant on coast_audio: ^0.0.4 and flutter_coast_audio_miniaudio: ^0.0.4

edit: When I try to just use coast_audio: ^0.0.4 and coast_audio_miniaudio: ^0.0.4 I still encounter the error, when using flutter_coast_audio_miniaudio and getting the error ma_bridge is mentioned, maybe somthing with its installation? I tried using WavAudioDecoder but id rather decode the mp3 audio

Is there a version of flutter_coast_audio_miniaudio that i can use that wont give me the The method 'setString' isn't defined for the class 'Array<Char>'. error?

SKKbySSK commented 4 months ago

@MaayanBogin When you write ^ to the dependency, it will be resolved as a version range in >=0.0.4 <1.0.0. (reference) Can you write coast_audio: 0.0.4 instead of ^0.0.4?

MaayanBogin commented 4 months ago

@SKKbySSK Thanks for the response but I am officially really confused, I tried coast_audio: 0.0.4 , returned the same error, but its telling me I dont need the lib because of import flutter_coast_audio_miniaudio.dart';? so I dont need to import coast_audio(?)

Im not sure what lib to import anymore from all the repos pointing at smth else. Here are my imports import 'dart:async'; import 'dart:ffi' as ffi; import 'dart:io'; import 'dart:math' as math; import 'dart:typed_data'; import 'package:fftea/fftea.dart' //import 'package:coast_audio/coast_audio.dart'; *Note this is not used import 'package:flutter_coast_audio_miniaudio/flutter_coast_audio_miniaudio.dart';

Here is the relevant code regarding the decoding

final dataSource = AudioFileDataSource(file: file, mode: FileMode.read);
    // Determine the output format (assuming you know the format)
    final outputFormat =
        AudioFormat(sampleRate: 44100, channels: 1); // Adjust as needed
    // Create a buffer size
    final bufferSize = 4096;

    // Use ffi to allocate memory for the buffer
    final pBuffer = memory.allocator.allocate<ffi.Uint8>(bufferSize);

    // Create a MabAudioDecoder
     final decoder =
        MabAudioDecoder(dataSource: dataSource, outputFormat: outputFormat);

    //final decoder = WavAudioDecoder(dataSource: dataSource);  **Not used for now 
    final audioData = <double>[];

    // Decode audio data in chunks
    while (true) {
      final decodeResult = await decoder.decode(
        destination: AudioBuffer(
          pBuffer: pBuffer,
          sizeInBytes: bufferSize,
          sizeInFrames: bufferSize ~/ outputFormat.channels,
          format: outputFormat,
          memory: memory, // Pass the memory instance
        ),
      );

      // Check if decoding is finished
      if (decodeResult.isEnd) {
        break;
      }

      // Convert the decoded data in memory to a Dart List<double>
      for (var i = 0; i < decodeResult.frames * outputFormat.channels; i++) {
        final byte = pBuffer.elementAt(i).value;
        audioData.add(byte.toDouble());
      }
    }

Little side note : At this point I'm starting to get really confused, I'm not sure what to import and what statements to call, I simply need to decode mp3 audio data so i can do spectrum analyzation using fft, I'm sorry this is taking so long to resolve and I'm sure better developers would get through this quickly but I cant seem to get MabAudioDecoder or any MabAudio to be called while using flutter_coast_audio_miniaudio because it gives me the "'setString' isn't defined" error but when I try to use coast_audio there simply is no way to decode mp3

please help me :')

aveia commented 3 months ago

@MaayanBogin you don't need the import 'package:coast_audio/coast_audio.dart' statement in the source files; just add coast_audio: 0.0.4 to your pubspec.yaml (but keep flutter_coast_audio_miniaudio there too) so that flutter doesn't try to update the transitive dependency on coast_audio to 0.0.5 and everything should work.

MaayanBogin commented 3 months ago

Hello :) do you have plans on addressing this issue with flutter_coast_audio_miniaudio?

SKKbySSK commented 3 months ago

@MaayanBogin There is a plan for the next stable release. flutter_coast_audio_miniaudio and coast_audio_miniaudio will be integrated to the coast_audio package. (and it will introduces some breaking changes)

It should be released soon.