Jump to content


Photo

Writing AIFF files


  • Please log in to reply
29 replies to this topic

#26 4Tey

4Tey

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 381 posts
  • Gender:Male

Posted 10 January 2017 - 20:25

Yeah, kinda tricky to explain afta8, but I shall try with this:

samphex.png

 

The top line is a partial hex dump of our 'lua_export.aiff' SSND chunk.  The bottom line is 'xfer_util.aiff' SSND chunk.  See the 3 differences?  Near the end of both lines we have sample 1 and sample 2 reading FB 8A (sample 1) and 01 2E (sample 2) in the other file FB 8A and 01 2D.  But I think we know that that is to do with my hacky/dodgy calculation afta8 that you will eventually correct ;)  Anyway I'm not concerned with that so much at all, it's the other two.

 

Looking near the beginning of each line we have 00 00 E1 C6 and 00 00 E1 BC. That is the length of the chunk.  So in this case 0xE1C6 = 57798 bytes and 0xE1BC = 57788 bytes.  That's a difference of 10 bytes.  The final difference is there is an extra 4 zeros in the xfer file before you get to sample 1.  Don't know afta8 about that, the length bothers me and those 4 zeros :)


  • afta8 likes this

#27 afta8

afta8

    Big Super GrandMasta Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPip
  • 709 posts
  • Gender:Male
  • Location:London

Posted 10 January 2017 - 22:11

I think this is something to do with how xfer_util processes the sounds, it looks like it is inserting 2 samples of silence at the start of the sample, if you open both in Renoise you can see that lua_export.aiff is 28889 samples long and xfer_util.aif is 28891 samples long, if you zoom into the beginning of the samples you can see 2 sample frames of silence. My guess is that is something to do with how the xfer util prepares the samples rather than any conversion code.


  • 4Tey likes this

#28 afta8

afta8

    Big Super GrandMasta Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPip
  • 709 posts
  • Gender:Male
  • Location:London

Posted 10 January 2017 - 23:36

So I have this sort of working, well in a specific test case version. See attached, if you use this version of the tool and the attached wav file the output will match the earlier, "xfer_util.aif" I posted. It also works when imported to OP1, slice position preserved etc.. 

 

Couple of things I need to figure out though.

 

If you look in a hex editor at the output file, there is a section after the APPL, see image:

Screen Shot 2017-01-10 at 22.14.26.png

 

At the moment I am just copying this from the original file to make it work, but I need to work out how to calculate this properly, if you look at this link: http://paulbourke.ne...aformats/audio/

Under the section on Application Specific Chunk it says:

 

 

Application Specific Chunk

The Application Specific Chunk can be used for any purposes whatsoever by manufacturers of applications. For example, an application that edits sounds might want to use this chunk to store editor state parameters such as magnification levels, last cursor position, and the like.

#define ApplicationSpecificID 'APPL' /* ckID for Application */
/* Specific Chunk. */
typedef struct {
ID ckID;
long ckSize;
OSType applicationSignature;
char data[];
} ApplicationSpecificChunk;

ckID is always 'APPL'. ckSize is the size of the data portion of the chunk, in bytes. It does not include the 8 bytes used by ckID and ckSize.

 

So I guess these 8 digits represent the size of the data in bytes, but how to work that out?

 

Also at the end of the data portion there is 6 digits:

Screen Shot 2017-01-10 at 22.15.13.png

 

If you take these out the file doesn't load but I'm not sure these are for?

 

 

Finally I need to work out how the sample frame position translates to the numbers in the data format, for example the start position in the data format is given as: 75324246, however the sample frame number is 18564, not sure how you go from one to the other..

 

Other than all that, I'm nearly there :D

 

 

 

Attached Files



#29 4Tey

4Tey

    Chief Above Chief Member

  • Normal Members
  • PipPipPipPipPipPip
  • 381 posts
  • Gender:Male

Posted 11 January 2017 - 06:52

Hmm afta8, I wonder why that xfer util inserts two samples of silence at the beginning?  I assume it would also have to adjust any loop points etc?... The length calculation still bothers me a touch...anyway... :)

 

As I far as I can see afta8 the 4 length bytes following the APPL string is just the length of the string:

samphex2.png

In the file 'op1_native' above I've highlighted the APPL string, it is 0x4AE (1198) bytes long.  I also see that this particular string is terminated with 0x0A (just a unix end of line terminator?)  Of course what you've eventually got to do afta8 is to 'pre build' your string (with all your parameters from your tool etc..), calculate the length (including any line termination), then insert that info into the file APPL chunk.

 

Don't know about your sample start position as this is to do with the OP-1 afta8.  But I understand what you mean, could be tricky :)

 

Edit:

 

The other thing to mention/consider (not more things  :rolleyes: ) afta8 in mxb's aiff function is line 30 (from the file you attached):

30  f:write(hex_pack(string.format("%08X", length))) -- chunk size = file length - 8 

Where mxb computes the overall file length.  To be more proper that also would have to be adjusted to accommodate your APPL chunk size.  But I suppose it also depends on how lenient the OP-1 import is :)

 


Edited by 4Tey, 11 January 2017 - 07:13.


#30 afta8

afta8

    Big Super GrandMasta Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPip
  • 709 posts
  • Gender:Male
  • Location:London

Posted 11 January 2017 - 09:00

Those two samples at the beginning are bothering me also, however seems to work ok for now, I'll leave those on the list of things to come back to.

The length thing makes sense now, so I just need to have one long string and calculate it's size in bytes. I also realised that the OP1 data is in JSON format so I can just use a LUA/JSON library which should make this bit easier.

 

The overall file length I hadn't thought about but it has not been an issue so far, will see how far I get without touching it :)

 

I was also searching through Github and found a couple of projects where this mission has already been tackled.

https://github.com/padenot/libop1

https://github.com/o...kitBuilder.java

 

This will maybe help with some of these issues I have found, I already figured that the sample slice points are based on the bytes in the sample data.


  • 4Tey likes this