UADE2 chronicles
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    BSzili
    Posts: 559 from 2012/6/8
    From: Hungary
    I'm not dead yet, it's just that the uade2 ANR player eats up all the free time I can dedicate to MorphOS. After some false starts I finally have a clear idea on how to get things together, but I have some questions.
    Are there any good info on making shared libraries out there? Can I compile them with GCC4? Do I have to use some specific compiler/linker flags? I tried looking some makefiles, but they are all over the place. Also are there any restriction on using LibNIX functions?
    The other thing is AHI double buffering. I made an AHI backend for uade123, and it sometimes hangs at the beginning of the playback. This is how the source looks like:

    Code:
    #include <stdlib.h>

    #include <devices/ahi.h>
    #include <proto/exec.h>

    #ifndef __MORPHOS__
    #define AllocTaskPooled(size) AllocMem(size, MEMF_ANY)
    #define FreeTaskPooled(mem, size) FreeMem(mem, size)
    #endif

    #include "uadeconstants.h"
    #include "audio.h"
    #include "uade123.h"

    /* this is hardcoded baby! */
    #if (UADE_BYTES_PER_SAMPLE == 1)
    #if (UADE_CHANNELS == 1)
    #define type AHIST_M8S
    #elif (UADE_CHANNELS == 2)
    #define type AHIST_S8S
    #else
    #error Invalid channel number.
    #endif
    #elif (UADE_BYTES_PER_SAMPLE == 2)
    #if (UADE_CHANNELS == 1)
    #define type AHIST_M16S
    #elif (UADE_CHANNELS == 2)
    #define type AHIST_S16S
    #else
    #error Invalid channel number.
    #endif
    #else
    #error Invalid bytes per sample value.
    #endif

    #define BUFSIZE (8192 * UADE_BYTES_PER_SAMPLE * UADE_CHANNELS)
    static char AHIBuf[2][BUFSIZE];

    static ULONG rate;
    static struct MsgPort *AHIPort = NULL;
    static struct AHIRequest *AHIReq[2] = { NULL, NULL };

    static int active = 0;
    static int slots = 2;

    void audio_close (void)
    {
    if (AHIReq[1])
    {
    if (!CheckIO((struct IORequest *) AHIReq[1]))
    {
    AbortIO((struct IORequest *) AHIReq[1]);
    WaitIO((struct IORequest *) AHIReq[1]);
    }
    FreeTaskPooled(AHIReq[1], sizeof(struct AHIRequest));
    AHIReq[1] = NULL;
    }

    if (AHIReq[0])
    {
    if (!CheckIO((struct IORequest *) AHIReq[0]))
    {
    AbortIO((struct IORequest *) AHIReq[0]);
    WaitIO((struct IORequest *) AHIReq[0]);
    }
    if (AHIReq[0]->ahir_Std.io_Device)
    {
    CloseDevice((struct IORequest *) AHIReq[0]);
    AHIReq[0]->ahir_Std.io_Device = NULL;
    }
    DeleteIORequest((struct IORequest *) AHIReq[0]);
    AHIReq[0] = NULL;
    }

    if (AHIPort)
    {
    DeleteMsgPort(AHIPort);
    AHIPort = NULL;
    }
    }

    int audio_init(const struct uade_config *uc)
    {
    if (uade_no_audio_output)
    return 1;

    rate = uc->frequency;

    if ((AHIPort = CreateMsgPort()))
    {
    if ((AHIReq[0] = (struct AHIRequest *) CreateIORequest(AHIPort, sizeof(struct AHIRequest))))
    {
    AHIReq[0]->ahir_Version = 4;
    if ((AHIReq[1] = (struct AHIRequest *) AllocTaskPooled(sizeof(struct AHIRequest))))
    {
    if (!OpenDevice("ahi.device", AHI_DEFAULT_UNIT, (struct IORequest *)AHIReq[0], 0))
    {
    AHIReq[0]->ahir_Std.io_Command = CMD_WRITE;
    AHIReq[0]->ahir_Std.io_Offset = 0;
    AHIReq[0]->ahir_Type = type;
    AHIReq[0]->ahir_Frequency = rate;
    AHIReq[0]->ahir_Volume = 0x10000;
    AHIReq[0]->ahir_Position = 0x8000;

    CopyMemQuick(AHIReq[0], AHIReq[1], sizeof(struct AHIRequest));
    return 1;
    }
    FreeTaskPooled(AHIReq[1], sizeof(struct AHIRequest));
    }
    DeleteIORequest((struct IORequest *) AHIReq[0]);
    }
    DeleteMsgPort(AHIPort);
    }

    return 0;
    }

    int audio_play(unsigned char* output_samples, int num_bytes)
    {
    int size;

    if (uade_no_audio_output)
    return 1;

    while (num_bytes)
    {
    WaitIO((struct IORequest *) AHIReq[active]);

    size = (BUFSIZE > num_bytes) ? num_bytes : BUFSIZE;
    CopyMem(output_samples, AHIBuf[active], num_bytes);
    num_bytes -= size;

    AHIReq[active]->ahir_Std.io_Data = AHIBuf[active];
    AHIReq[active]->ahir_Std.io_Length = size;
    AHIReq[active]->ahir_Link = AHIReq[active ^ 1];

    SendIO((struct IORequest *) AHIReq[active]);

    // swap buffers
    active ^= 1;
    }

    return 1;
    }

    are there any obvious problems there?
    This is just like television, only you can see much further.
  • »05.01.13 - 16:06
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    BSzili
    Posts: 559 from 2012/6/8
    From: Hungary
    This is not about the ANR plugin yet, which is in development hell currently. I have some idea how it all should work together (library, playloop task, uadecore), but I have no time and energy to finish it for the time being. ANR also locks up my system at exit, so even if I resumed the work on the plugin, I wouldn't be able to test it.
    However I fixed some nasty bugs in the uade123 command line player, including the problems (hits, crashes) with the code above. You also won't need an UADE: assign anymore, just make sure uade123 and uadecore are in the same drawer.
    This is just like television, only you can see much further.
  • »24.07.13 - 19:51
    Profile Visit Website
  • Paladin of the Pegasos
    Paladin of the Pegasos
    pampers
    Posts: 1061 from 2009/2/26
    From: Tczew, Poland
    Quote:

    BSzili wrote:
    This is not about the ANR plugin yet, which is in development hell currently. I have some idea how it all should work together (library, playloop task, uadecore), but I have no time and energy to finish it for the time being. ANR also locks up my system at exit, so even if I resumed the work on the plugin, I wouldn't be able to test it.
    However I fixed some nasty bugs in the uade123 command line player, including the problems (hits, crashes) with the code above. You also won't need an UADE: assign anymore, just make sure uade123 and uadecore are in the same drawer.


    How about integrating it somehow with Jukebox - possible? Or even better - UADE reggae decoder :)


    [ Edited by pampers 24.07.2013 - 21:38 ]
    MorphOS 3.x
  • »24.07.13 - 20:37
    Profile Visit Website
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Intuition
    Posts: 1110 from 2013/5/24
    From: Nederland
    Is Piru's source no help from the port he made years ago?
    1.67GHz 15" PowerBook G4, 1GB RAM, 128MB Radeon 9700M Pro, 64GB SSD, MorphOS 3.15

    2.7GHz DP G5, 4GB RAM, 512MB Radeon X1950 Pro, 500GB SSHD, MorphOS 3.9
  • »24.07.13 - 21:14
    Profile
  • Yokemate of Keyboards
    Yokemate of Keyboards
    Andreas_Wolf
    Posts: 12241 from 2003/5/22
    From: Germany
    > Is Piru's source no help from the port he made years ago?

    In think he already looked at that:

    https://morph.zone/modules/newbb_plus/viewtopic.php?forum=32&topic_id=6961&start=45
  • »24.07.13 - 22:03
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Intuition
    Posts: 1110 from 2013/5/24
    From: Nederland
    Quote:

    Andreas_Wolf wrote:
    > Is Piru's source no help from the port he made years ago?

    In think he already looked at that:

    https://morph.zone/modules/newbb_plus/viewtopic.php?forum=32&topic_id=6961&start=45


    Perhaps he should write to the FSF asking if an ANR plugin would indeed violate the GPL?
    1.67GHz 15" PowerBook G4, 1GB RAM, 128MB Radeon 9700M Pro, 64GB SSD, MorphOS 3.15

    2.7GHz DP G5, 4GB RAM, 512MB Radeon X1950 Pro, 500GB SSHD, MorphOS 3.9
  • »25.07.13 - 00:26
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    BSzili
    Posts: 559 from 2012/6/8
    From: Hungary
    @Intuition:
    It's not a concern ATM, because the ANR plugin is shelved, as I wrote in my last post.

    @pampers:
    AFAIK Jukebox uses reggae classes, so the first would imply the latter. I don't think it would be much easier than the ANR plugin. Is there any documentation out there on writing reggae classes?
    This is just like television, only you can see much further.
  • »25.07.13 - 08:08
    Profile Visit Website