Author Topic: BASSenc_AAC (AAC encoding)  (Read 14135 times)

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #25 on: 5 Nov '23 - 16:59 »
I also used this method

Same problem, no sound ERROR 41

public void playReceivedData(byte[] data) {
        MyFileProcs procs = new MyFileProcs(data);

        int channel = com.un4seen.bass.BASS_AAC.BASS_AAC_StreamCreateFileUser( STREAMFILE_BUFFERPUSH, BASS_STREAM_DECODE, procs, null);

        if (channel == 0) {
            int error = BASS.BASS_ErrorGetCode();
            System.out.println("Error playing data: " + error);
        } else {
            BASS.BASS_ChannelPlay(channel, false);
        }
    }

    private class MyFileProcs implements BASS.BASS_FILEPROCS {
        private final byte[] data;
        private int position = 0;

        public MyFileProcs(byte[] data) {
            this.data = data;
        }

        @Override
        public int FILEREADPROC(ByteBuffer buffer, int length, Object user) {
            int bytesToCopy = Math.min(length, data.length - position);
            if (bytesToCopy <= 0) {
                return -1; // EOF
            }
            buffer.put(data, position, bytesToCopy);
            position += bytesToCopy;
            return bytesToCopy;
        }

        @Override
        public long FILELENPROC(Object user) {
            return data.length;
        }

        @Override
        public void FILECLOSEPROC(Object user) {}

        @Override
        public boolean FILESEEKPROC(long offset, Object user) {
            if (offset < 0 || offset > data.length) {
                return false;
            }
            position = (int) offset;
            return true;
        }

    }

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #26 on: 6 Nov '23 - 14:48 »
To narrow down what/where the problem is, if you just write the encoded data to a file (not network) and then try playing that file, does that work?

If you want to send the data over a network, you could try BASSenc's built-in server feature (see BASS_Encode_ServerInit) and then BASS_StreamCreateURL on the client side. That should make things much simpler for you, eg. no need for callback functions. You can check the SERVER.C example (and pre-compiled SERVER.EXE) included in the BASSenc package for a demonstration.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #27 on: 6 Nov '23 - 17:01 »
To narrow down what/where the problem is, if you just write the encoded data to a file (not network) and then try playing that file, does that work?

If you want to send the data over a network, you could try BASSenc's built-in server feature (see BASS_Encode_ServerInit) and then BASS_StreamCreateURL on the client side. That should make things much simpler for you, eg. no need for callback functions. You can check the SERVER.C example (and pre-compiled SERVER.EXE) included in the BASSenc package for a demonstration.

I tried it and the same problem. Changing using all types has the same problem 


As for BASS_Encode_ServerInit, I used it and it succeeded, but there is a delay and I want to transfer in real time, so I used this method


                encodeHandle=     BASS_Encode_AAC_Start(recordChannel, "--object-type 2 --vbr 0 --bitrate 32000", 0,  encodeProcx,null);

 public static com.un4seen.bass.BASSenc.ENCODEPROCEX  encodeProcx = (int handle, int channel, ByteBuffer buffer, int length, long offset, Object user) -> {
        byte[] data = new byte[length];
      buffer.get(data);
     sendEncodedData(data);

    };

 ByteBuffer byteBuffer = ByteBuffer.wrap(encodedData);
        int channel = BASS_AAC_StreamCreateFile(byteBuffer, 0, encodedData.length, 0);

 BASS.BASS_ChannelPlay(channel, false);

AAC, OGG , OPUS   All Type  same problem 


Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #28 on: 6 Nov '23 - 17:32 »
I tried it and the same problem. Changing using all types has the same problem 

Strange. Please show the code you used to write the file, and the code you used to try to play it afterwards. Also try BASS_Encode_AAC_StartFile instead of BASS_Encode_AAC_Start, to check if the issue is something in your callback function.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #29 on: 6 Nov '23 - 17:51 »
When I send the data to the server and save it in a file, I can read it using VLC
The problem is reading the data

 ByteBuffer byteBuffer = ByteBuffer.wrap(encodedData);
        int channel = BASS_AAC_StreamCreateFile(byteBuffer, 0, encodedData.length, 0);

 BASS.BASS_ChannelPlay(channel, false); 

error 41
« Last Edit: 6 Nov '23 - 18:40 by orange »

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #30 on: 7 Nov '23 - 12:07 »
When I send the data to the server and save it in a file, I can read it using VLC

If you try opening the same file (not a ByteBuffer) with BASS_StreamCreateFile, does that work? If not, please upload (or link) the file to have a look at here:

   ftp.un4seen.com/incoming/

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #31 on: 7 Nov '23 - 21:37 »
I could not play the file

  audioFilePath := 'output.aac';

  stream := BASS_StreamCreateFile(False, PChar(audioFilePath), 0, 0, 0);

error  2

I sent you the file   ftp.un4seen.com/incoming/


===============

I tried writing codes in Java and Delphi, but the problem is the same. Recording and compression works, but playing the file does not work
« Last Edit: 7 Nov '23 - 23:17 by orange »

Chris

  • Posts: 2203
Re: BASSenc_AAC (AAC encoding)
« Reply #32 on: 7 Nov '23 - 23:48 »
Hi looks like you have a newer Delphi Version so


Code: [Select]
var
  AAC_Plugin: HPlugin;
  Fstream:HStream;

AAC_Plugin := BASS_PluginLoad(PWideChar('bass_aac.dll'),BASS_UNICODE);
if AAC_Plugin = 0 then
 // Errorhandling eg Bass_ErrorGetCode
else
   Fstream := BASS_StreamCreateFile(False, PWideChar(audioFilePath), 0,0, BASS_UNICODE);
  if fStream = 0 then
   // Errorhandling eg Bass_ErrorGetCode



« Last Edit: 8 Nov '23 - 02:46 by Chris »

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #33 on: 8 Nov '23 - 12:37 »
Hi looks like you have a newer Delphi Version so


Code: [Select]
var
  AAC_Plugin: HPlugin;
  Fstream:HStream;

AAC_Plugin := BASS_PluginLoad(PWideChar('bass_aac.dll'),BASS_UNICODE);
if AAC_Plugin = 0 then
 // Errorhandling eg Bass_ErrorGetCode
else
   Fstream := BASS_StreamCreateFile(False, PWideChar(audioFilePath), 0,0, BASS_UNICODE);
  if fStream = 0 then
   // Errorhandling eg Bass_ErrorGetCode


Thanks Chris

I noticed that when the samples are saved in memory and then played, they work well, but the sound playback time is delayed by a second or more. The question here is: Is the Bass library unable to play samples in real time??

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #34 on: 8 Nov '23 - 14:32 »
The uploaded AAC file is playable with BASS_StreamCreateFile, so it seems like the issue may be something in your callback functions when using BASS_StreamCreateFileUser. Is your "playReceivedData" function called for each packet of data? If so, you shouldn't create a new stream for each packet, but rather create a single stream from the first packet and then feed the other packets to that too via BASS_StreamPutFileData. Your FILELENPROC should return 0 so that the stream doesn't end after the first packet. Note you should also pass any remaining data (not used by BASS_StreamCreateFileUser) from the first packet to BASS_StreamPutFileData after BASS_StreamCreateFileUser returns.

If you're still getting a BASS_ERROR_FILEFORM error from BASS_StreamCreateFileUser then it may be that your first packet doesn't contain enough data, in which case you can buffer the data and call BASS_StreamCreateFileUser when you have more.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #35 on: 8 Nov '23 - 17:15 »
The uploaded AAC file is playable with BASS_StreamCreateFile, so it seems like the issue may be something in your callback functions when using BASS_StreamCreateFileUser. Is your "playReceivedData" function called for each packet of data? If so, you shouldn't create a new stream for each packet, but rather create a single stream from the first packet and then feed the other packets to that too via BASS_StreamPutFileData. Your FILELENPROC should return 0 so that the stream doesn't end after the first packet. Note you should also pass any remaining data (not used by BASS_StreamCreateFileUser) from the first packet to BASS_StreamPutFileData after BASS_StreamCreateFileUser returns.

If you're still getting a BASS_ERROR_FILEFORM error from BASS_StreamCreateFileUser then it may be that your first packet doesn't contain enough data, in which case you can buffer the data and call BASS_StreamCreateFileUser when you have more.


Good, I understand. I will try it and I will let you know the results. Thank you very much

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #36 on: 8 Nov '23 - 19:28 »
Is it possible for a simple example of how to read the data? It did not work for me. I do not know where the problem is  ??? ???

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #37 on: 9 Nov '23 - 11:43 »
Is your BASS_StreamCreateFileUser call still failing with BASS_ERROR_FILEFORM? If so, how much data are you providing it via your FILEREADPROC? The ADTS parser currently expects to see at least 3 ADTS frames to confirm that it is actually ADTS data. If you have less than that, try downloading more before calling BASS_StreamCreateFileUser and see if you still have the problem then.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #38 on: 9 Nov '23 - 18:30 »
Is your BASS_StreamCreateFileUser call still failing with BASS_ERROR_FILEFORM? If so, how much data are you providing it via your FILEREADPROC? The ADTS parser currently expects to see at least 3 ADTS frames to confirm that it is actually ADTS data. If you have less than that, try downloading more before calling BASS_StreamCreateFileUser and see if you still have the problem then.

wrote the code in Delphi to verify the problem, but it is the same  StreamHandle = 0


Code: [Select]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer, Bass;

type
  TForm1 = class(TForm)
    IdUDPServer1: TIdUDPServer;
    procedure IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
      const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    StreamHandle: HSTREAM;
    AudioData: TBytes;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function FileReadProc(buffer: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
begin
  if Assigned(user) then
  begin
    Move(PByteArray(user)^, buffer^, length);
    Result := length;
  end
  else
  begin
    Result := 0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  FileProcs: BASS_FILEPROCS;
begin
  if BASS_Init(-1, 44100, 0, 0, nil) then
  begin
    FileProcs.READ := @FileReadProc;
 
    FileProcs.CLOSE := nil;
    FileProcs.LENGTH := nil;
    FileProcs.READ := nil;
    FileProcs.SEEK := nil;
   
    StreamHandle := BASS_StreamCreateFileUser(STREAMFILE_NOBUFFER or BASS_STREAM_DECODE, BASS_STREAMFILE_BUFFER, @FileProcs, AudioData);

    if StreamHandle <> 0 then
    begin
      BASS_ChannelPlay(StreamHandle, False);
    end
    else
    begin
      ShowMessage('Error playing audio');
    end;
  end
  else
  begin
    ShowMessage('BASS initialization error');
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if StreamHandle <> 0 then
    BASS_StreamFree(StreamHandle);

  BASS_Free;
end;

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  SetLength(AudioData, Length(AData));
  Move(AData[0], AudioData[0], Length(AData));
 // BASS_StreamPutFileData(StreamHandle, @AData[0], Length(AData));
end;

end.





 
« Last Edit: 9 Nov '23 - 21:00 by orange »

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #39 on: 10 Nov '23 - 12:41 »
Code: [Select]
function FileReadProc(buffer: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
begin
  if Assigned(user) then
  begin
    Move(PByteArray(user)^, buffer^, length);
    Result := length;
  end
  else
  begin
    Result := 0;
  end;
end;

This function should advance the read position by the amount that it returned, so that the next call doesn't return the same data. It also needs to check that the "length" parameter doesn't exceed the amount of data available. I'm not a Delphi user myself, but in C/C++ it could look something like this:

Code: [Select]
DWORD CALLBACK FileReadProc(void *buffer, DWORD length, void *user)
{
if (length > datalen - datapos) length = datalen - datapos; // limit it to available amount
memcpy(buffer, data + datapos, length); // read data
datapos += length; // advance read position
return length; // return read amount
}

Code: [Select]
    FileProcs.READ := @FileReadProc;
 
    FileProcs.CLOSE := nil;
    FileProcs.LENGTH := nil;
    FileProcs.READ := nil;
    FileProcs.SEEK := nil;
   
    StreamHandle := BASS_StreamCreateFileUser(STREAMFILE_NOBUFFER or BASS_STREAM_DECODE, BASS_STREAMFILE_BUFFER, @FileProcs, AudioData);

FileProcs.READ is nil?

For a file from the internet, you should usually use either the STREAMFILE_BUFFER or STREAMFILE_BUFFERPUSH systems (not STREAMFILE_NOBUFFER), depending on whether you want to use BASS_StreamPutFileData. Also, BASS_STREAM_DECODE should be in the "flags" parameter rather than the "system" parameter. For example:

Code: [Select]
    StreamHandle := BASS_StreamCreateFileUser(STREAMFILE_BUFFERPUSH, BASS_STREAM_DECODE, @FileProcs, AudioData);

But it looks like you're currently calling BASS_StreamCreateFileUser without any data available? It needs to see some data (from the FILEREADPROC) to detect the format and initialize a decoder, so you should download some data before that.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #40 on: 10 Nov '23 - 13:15 »
I seem to have overlooked this   FileProcs.READ := nil;
Thank you very much for the answers to my questions. I will fix the problem based on your answer
« Last Edit: 10 Nov '23 - 14:48 by orange »

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #41 on: 10 Nov '23 - 19:05 »
 
Code: [Select]
if (StreamHandle = 0) and (AudioData <> nil) then
  begin
    StreamHandle := BASS_AAC_StreamCreateFileUser(STREAMFILE_BUFFER OR STREAMFILE_BUFFERPUSH, BASS_STREAM_DECODE,  FileProcs, AudioData);
    if StreamHandle = 0 then
    begin
 Memo1.Lines.Add('Error creating BASS stream: ' + IntToStr(BASS_ErrorGetCode));
    end;
  end;

Error creating BASS stream: 20

Chris

  • Posts: 2203
Re: BASSenc_AAC (AAC encoding)
« Reply #42 on: 11 Nov '23 - 12:07 »
Quote
STREAMFILE_BUFFER OR STREAMFILE_BUFFERPUSH

why are you placing both in the first Parameter ?
STREAMFILE_BUFFER  = buffered stream
STREAMFILE_BUFFERPUSH = Buffered, with the data pushed to BASS via BASS_StreamPutFileData

So only one of the both.

orange

  • Posts: 13
Re: BASSenc_AAC (AAC encoding)
« Reply #43 on: 12 Nov '23 - 13:37 »
Thank you very much, but nothing worked for me
I don't know where the problem is when there is an example of everything in Lib. I searched a lot in the forum and did not find  ??? ??? ???

Ian @ un4seen

  • Administrator
  • Posts: 25780
Re: BASSenc_AAC (AAC encoding)
« Reply #44 on: 13 Nov '23 - 16:09 »
What is it that you ultimately want to achieve? If it's low latency between recording and playing then you would probably be better off using Opus (instead of AAC) with the recent BASSenc_OPUS and BASSOPUS updates, which should also be simpler for you because you don't need any BASS_FILEPROCS callbacks. The updates are in this thread:

   www.un4seen.com/forum/?topic=20236.msg141570#msg141570

alicom

  • Posts: 19
Re: BASSenc_AAC (AAC encoding)
« Reply #45 on: 21 Dec '23 - 07:51 »
I am trying to record audio to AAC using the ManagedBass.Enc wrapper:

Code: [Select]
    Sub RecTTS()

        If Bass.Init(-1, 44100, DeviceInitFlags.Default, IntPtr.Zero) AndAlso Bass.RecordInit(-1) Then

            Dim recordProc As RecordProcedure = AddressOf RecordCallback
            Dim recordingStream As Integer = Bass.RecordStart(44100, 2, BassFlags.RecordPause, recordProc, IntPtr.Zero)

            If recordingStream <> 0 Then

                BassEnc.EncodeStart(Handle:=recordingStream, CommandLine:="true_recorded_audio.aac", Flags:=BassFlags.AacStereo Or BassFlags.AutoFree, Nothing, IntPtr.Zero)
                Bass.ChannelPlay(recordingStream)

                Console.WriteLine("Recording started. Press any key to stop.")
                Console.ReadKey()

                Bass.ChannelStop(recordingStream)
                BassEnc.EncodeStop(recordingStream)
                Bass.RecordFree() ' Free recording resources

                Console.WriteLine("Recording saved to file")

            Else

                Console.WriteLine("Failed to start recording.")

            End If

            Bass.Free()

        Else

            Console.WriteLine("Failed to initialize Bass.")

        End If

        Console.WriteLine("Press any key to exit.")
        Console.ReadKey()

    End Sub


    Public Function RecordCallback(handle As Integer, buffer As IntPtr, length As Integer, user As IntPtr) As Boolean

        Return True

    End Function

The output file is not being written. Is ManagedBass.Enc addon sufficient to write AAC file? Am I making any mistakes with the flags? Many thanks.
« Last Edit: 21 Dec '23 - 09:49 by alicom »

Chris

  • Posts: 2203
Re: BASSenc_AAC (AAC encoding)
« Reply #46 on: 21 Dec '23 - 10:43 »
Hi latest ManagedBass (3.1.1) was from 04.2022,  aac was added 09.2022.
https://github.com/ManagedBass/ManagedBass/pull/117/commits/70a1f556f4a8d2f7de39f11c4c3eb9bd17032154

alicom

  • Posts: 19
Re: BASSenc_AAC (AAC encoding)
« Reply #47 on: 21 Dec '23 - 12:15 »
Many thanks. On a side note, can ManagedBass only natively play wav, mp3, ogg and flac? I could see that ManagedBass.Enc can record opus, but I could not play that by creating stream. Or was I missing a particular flag?

Chris

  • Posts: 2203
Re: BASSenc_AAC (AAC encoding)
« Reply #48 on: 21 Dec '23 - 13:41 »
This is a List of the supported AddOns.
The simplest way is to do it via e.g  Bass_PluginLoad("bassopus.dll") .
then you can load it via Bass_StreamCreateFile...

alicom

  • Posts: 19
Re: BASSenc_AAC (AAC encoding)
« Reply #49 on: 21 Dec '23 - 14:37 »
Many thanks  :)