Author Topic: unmo3 as a library?  (Read 50042 times)

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #25 on: 12 Dec '13 - 15:35 »
That's strange, as the library should be thread-safe. I quickly tried reproducing the problem with the following code, but it never happened.

Code: [Select]
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "unmo3.h"

void *buf;
unsigned len;

DWORD WINAPI threadproc(void *p)
{
while (1) {
void *buf0=buf;
unsigned len0=len;
int r=UNMO3_Decode(&buf0, &len0, 0);
printf("%d: unmo3=%d\n", (int)p, r);
if (!r) UNMO3_Free(buf0);
}
return 0;
}

int main(int argc, char **argv)
{
FILE *f;
if (argc<2) return 0;
f=fopen(argv[1], "rb");
if (!f) return 0;
len=filelength(fileno(f));
buf=malloc(len);
fread(buf, len, 1, f);
fclose(f);
CreateThread(0, 0, threadproc, (void*)0, 0, 0);
CreateThread(0, 0, threadproc, (void*)1, 0, 0);
getchar();
return 0;
}

Can you produce the problem with something that?

kode54

  • Posts: 100
Re: unmo3 as a library?
« Reply #26 on: 13 Dec '13 - 04:51 »
I am using version 2.4.0.3, and I am also calling LoadLibrary/GetProcAddress/FreeLibrary from each thread which unpacks an MO3. It was the original way I dealt with bundling the library in my component's directory before the player started adding the components' own directories to the DLL search path in turn while each component is being loaded. I suppose I could change that now.

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #27 on: 13 Dec '13 - 13:44 »
I am using version 2.4.0.3

Ah, I think that would explain it. Thread-safety was added in 2.4.0.4. To ensure that the correct DLL version is loaded, you could check for the presence of the UNMO3_GetVersion function, which was also added in 2.4.0.4.

kode54

  • Posts: 100
Re: unmo3 as a library?
« Reply #28 on: 14 Dec '13 - 01:53 »
The problem isn't that someone is providing the wrong version, since I bundle my own copy. I just neglected to update the component. Let me take care of that right now.

Dr. Fiemost

  • Posts: 13
Re: unmo3 as a library?
« Reply #29 on: 2 Jan '14 - 21:55 »
Is this library supposed to support mp3 samples? I get mostly silent output from the mo3 I've tried.

saga

  • Posts: 2171
Re: unmo3 as a library?
« Reply #30 on: 2 Jan '14 - 22:18 »
You're right, MP3 sample support seems to be broken in the latest version indeed!
Here's an example file to demonstrate the problem.
I also noticed that a previous version of unmo3.dll (dated 2011) had a problem with this particular MO3 file; the belltree sample had some silence in the loop part of the sample. This doesn't happen in the latest XMPlay however, so it's probably already fixed.
« Last Edit: 2 Jan '14 - 22:28 by saga »

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #31 on: 3 Jan '14 - 16:12 »
Oops! There were some changes in the MP3 decoder, which the UNMO3 code hadn't been updated for yet. Here's an update that should sort it...

   www.un4seen.com/stuff/unmo3lib.zip

Let me know if it still gives you any trouble.

saga

  • Posts: 2171
Re: unmo3 as a library?
« Reply #32 on: 3 Jan '14 - 16:16 »
Yup, that seems to fix the problem. Thanks for the quick fix!

Dr. Fiemost

  • Posts: 13
Re: unmo3 as a library?
« Reply #33 on: 3 Jan '14 - 20:59 »
Thanks for the fix, works fine so far.

saga

  • Posts: 2171
Re: unmo3 as a library?
« Reply #34 on: 6 Feb '15 - 22:04 »
Since libopenmpt can use the unmo3 library as a "plug-in" to decode MO3 files, a couple of Android libopenmpt users have asked if this feature could be made on Android as well. Ian, would it be possible to port the library to Android as well?

CasualBoy

  • Posts: 5
Re: unmo3 as a library?
« Reply #35 on: 7 Feb '15 - 14:08 »
I am second to Saga proposal.
I would like to see Mo3 supported in my Android phone. ;D

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #36 on: 9 Feb '15 - 17:40 »
Since libopenmpt can use the unmo3 library as a "plug-in" to decode MO3 files, a couple of Android libopenmpt users have asked if this feature could be made on Android as well. Ian, would it be possible to port the library to Android as well?

I'll look into building an Android version this week. Have you already implemented the dynamic library loading for Android in your code? I recall that is a bit tricky/messy because the app's "lib" folder isn't in Android's library search path, so you need to provide the full path, which is tricky/messy to get in native code.

I would like to see Mo3 supported in my Android phone. ;D

If you happen to just want to play MO3 files, that is possible with the BASS library.

saga

  • Posts: 2171
Re: unmo3 as a library?
« Reply #37 on: 9 Feb '15 - 18:27 »
We didn't have a look yet, but I'll try to ask the people who're interested in the feature if they can help out. My own experience with Android is rather limited.

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #38 on: 12 Feb '15 - 17:09 »
OK. An Android version of the unmo3 library has now been added...

   www.un4seen.com/stuff/unmo3lib.zip

It's untested so far, so let me know if you have any trouble with it. As I mentioned, loading it in native code may be tricky due to the issue of getting the full path. It'll probably be simplest to load it from Java first, and then the native code shouldn't need the full path to access it.

Code: [Select]
System.loadLibrary("unmo3");

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #39 on: 14 Feb '15 - 16:57 »
Hi,

I tested the library and it seems to be produce too much decoded data. Decode function returned success but the filesize became over 15MB (encoded size is 473484 bytes). The real decoded size is around 4.7MB. Also the filesize and decoded contents change if you decode the same data several times in a row. Tested on Android x86.
« Last Edit: 14 Feb '15 - 17:14 by haspor »

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #40 on: 16 Feb '15 - 14:06 »
That's strange. I tried unmo3'ing a few files just now (on an ARMv7 device), and that seemed to go fine. In case the problem is something file-specific, please upload a MO3 file that you're having the problem with to have a look at here...

   ftp.un4seen.com/incoming/

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #41 on: 16 Feb '15 - 17:14 »
Hi,

this is the file: /incoming/BeyondNetwork.mo3

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #42 on: 17 Feb '15 - 20:29 »
Hi,

I uploaded Android ARMv7 device decoded file of BeyondNetwork.mo3:

 * ftp.un4seen.com/incoming/BeyondNetwork_AndroidARM_decoded.it

The decoded filesize is at least correct.

I decoded the BeyondNetwork.mo3 with unmo3.exe and compared it to the ARM decoded file. The beginning seems to be almost correct but starting from offset 0x46da2 its just zeroes.
« Last Edit: 17 Feb '15 - 20:54 by haspor »

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #43 on: 18 Feb '15 - 13:47 »
I was able to reproduce the problem in an x86 Android emulator. Here's an update that seems to be working properly...

   www.un4seen.com/stuff/unmo3lib.zip

Let me know if it's still not working properly there.

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #44 on: 18 Feb '15 - 17:31 »
Hi,

I will test. I noticed the ARMv7 version is still the same. Could you provide some simple example how to get it working on ARMv7? Android.mk file + how to properly access the library functions.


Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #45 on: 19 Feb '15 - 14:35 »
In my tests, I was just reading the MO3 file to memory, passing that memory block to UNMO3_Decode, and then writing the returned memory block to a new file. That's all in native code, using fopen/etc for the file stuff.

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #46 on: 19 Feb '15 - 15:06 »
Hi,

that's exactly what I did.

fopen, fread, decode and write back to a new file.

I suppose there is just one way to load the .so file and call its functions.

How is it even possible to fail then...I'll paste my code here later

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #47 on: 19 Feb '15 - 19:59 »
Hi,

tried the new version, little improvement. The decoded size is now correct but the file data is now equal to data I get when decoding with Android ARMv7a device -> at the beginning its ok but later it gets corrupted. I used the beyondnetwork.mo3 file.

How did you verify the decoded data is ok? Did you try to play the decoded file? Do verify that the data is equal to unmo3.exe decoded content please. Also check the offset i mentioned above.
« Last Edit: 19 Feb '15 - 21:09 by haspor »

Ian @ un4seen

  • Administrator
  • Posts: 20336
Re: unmo3 as a library?
« Reply #48 on: 20 Feb '15 - 17:24 »
Yep, the unmo3'd file seems to be fine here, ie. it sounds fine when played and there isn't the block of 0s that's in the file you uploaded. Do you get the block of 0s with other MO3 files too? I wonder if the problem is that the new file content hasn't been fully flushed to disk; are you calling fclose to close the file? If that's not it, you could check whether the memory block actually contains 0 before it is written. For example...

Code: [Select]
for (int a=0x46da2; a<length; a++) {
if (buffer[a]!=0) {
__android_log_print(ANDROID_LOG_DEBUG, "unmo3", "not 0 at %x", a);
break;
}
}

haspor

  • Posts: 19
Re: unmo3 as a library?
« Reply #49 on: 20 Feb '15 - 19:38 »
Here is my Android.mk file:
Code: [Select]
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := unmo3
LOCAL_SRC_FILES := unmo3lib/$(TARGET_ARCH_ABI)/libunmo3.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := unmo3unpacker
LOCAL_SRC_FILES := unmo3test.cpp
LOCAL_SHARED_LIBRARIES := unmo3
include $(BUILD_SHARED_LIBRARY)

Here's the C code that suppose to decode the .mo3 stuff:
Code: [Select]

#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include "com_example_unmo3test_MainActivity.h"

extern "C" {
}

#define WINAPI
#include "unmo3.h"

JNIEXPORT jint JNICALL Java_com_example_unmo3test_MainActivity_load_1and_1unpack(JNIEnv *env, jobject obj)
{
    int result;
    unsigned int filesize = 0;
    int comp_size = 0;
    void * filedata;
    FILE * file = NULL;
    FILE * file2 = NULL;

    filedata = malloc(6000000);

    file = fopen("/mnt/sdcard/Music/BeyondNetwork.mo3", "rb");
    fseek(file, 0, SEEK_END);
    comp_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    fread(filedata, 1, comp_size, file);
    result = UNMO3_Decode(&filedata, &filesize, 1); <----- 2nd param must be comp_size and 3rd set to 0
    file2 = fopen("/mnt/sdcard/Music/output.it", "wb");
    fwrite(filedata, 1, filesize, file2); <------ filesize has to be comp_size instead of filesize
    fclose(file2);
    fclose(file);
    UNMO3_Free(filedata);

    return 1;
}

That's it. Let me know what's wrong with it. Also before the offset 0x46da2 the data is also corrupted, random dword sized blocks are zero.

EDIT: the code problem is solved now. I marked the errors there.
« Last Edit: 21 Feb '15 - 08:55 by haspor »