Old 06-15-2018, 12:40 AM   #1
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default Q: Get source bits depth / bits per sample ?

Hi !


We have reaper.GetMediaSourceSampleRate( source ) but I don't see a function for bith depth, did I miss something ?


I found wav.lua parser but this Wav only (and under copyright ?)


Thanks for pointing the solution if I miss a trick :P

EDIT: only trick I can see for now is using a CLI tool like sow or BWFMetaEdit (this last one is for wav only)

EDIT: according to https://superuser.com/questions/5535...-aac-bit-depth, not all audio files have bit depth to report. This is an important point ^^

Last edited by X-Raym; 06-15-2018 at 02:20 AM.
X-Raym is offline   Reply With Quote
Old 06-15-2018, 02:46 AM   #2
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Switch to C++ and you could use PCM_source::GetBitsPerSample()...

But there's currently no ideal solution for ReaScript users, I guess.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by Xenakios; 06-15-2018 at 02:51 AM.
Xenakios is offline   Reply With Quote
Old 06-15-2018, 02:56 AM   #3
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Xenakios
I can go with BWF CLI for now but it is waaaay more verbose than a single line solution (the script need to check if it isnatlled, provide instruction if not, then run the CLI, parse the results etc, checking for OS...)


Do you think this function could be exposed to SWS ?
X-Raym is offline   Reply With Quote
Old 06-15-2018, 03:07 AM   #4
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Also, where did you find this function ? I don't see it in reaper_plugin_functions.h

EDIT: of I found it there:

www.reaper.fm/files/reaper_plugin.h

Last edited by X-Raym; 06-15-2018 at 03:14 AM.
X-Raym is offline   Reply With Quote
Old 06-15-2018, 03:33 AM   #5
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by X-Raym View Post
Do you think this function could be exposed to SWS ?
Very easily. (Assuming of course one has the SWS plugin build set up working, which I don't have.)
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 06-15-2018, 03:51 AM   #6
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Xenakios
Ok, I wrote a FR to SWS team
https://github.com/reaper-oss/sws/issues/1010


Thanks for your expertise !


(can't wait to ditch my 100 lines of code which are currently taking care of this ^^)
X-Raym is offline   Reply With Quote
Old 06-15-2018, 04:05 AM   #7
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by X-Raym View Post
(can't wait to ditch my 100 lines of code which are currently taking care of this ^^)
Note that the Reaper PCM_source function probably just returns 32/64 bits (or maybe even 0, I haven't extensively tested) for any non-clear cases like mp3s or FLACs, so the function might not be as useful as you think. What do you need it for, anyway?
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 06-15-2018, 04:23 AM   #8
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Quote:
for any non-clear cases like mp3s or FLACs,
It is not clear but it does exist for Flac:
http://take.ms/O5iCZ



In my exact particular case, this is not a too much a problem,
cause my script already take care of non-wav file before.


It is a script for selecting all items which could need render for AATranslator workflow.


So it select all files with take FX, stretch markers, sample rate different than project rate, bit depth different than a certain expected target, and few other criteria, to then be able to render selected items... and before that, it will select all non wav source files too so it is ok.


I guess for different file format, maybe sox, or ffprobe could be used (as BWF also only take care of WAV).
X-Raym is offline   Reply With Quote
Old 06-15-2018, 04:33 AM   #9
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

OK, you should be fine if you just get the function available in ReaScript.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Old 06-15-2018, 06:43 AM   #10
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

Xenakios, it's good! Support for different formats, plus we will not have to read the file manually in simple cases!

-----------------------
For X-Raym - I have something in Lua and EEL, but only for wav files.
However, maybe this will be useful in other cases (?)
These are only old tests, so many are not enough(some wav-formats etc), but it's very easy to complete.

Write wave-file from array of number directly from lua/eel.
gen_CreateWaveFile.eel
Create WAVE file from array of numbers.lua

-----------------------
I also have an old script, there you can see how to read / write a certain section of the file without affecting the entire file, also directly from the script.
gen_SampleEditor.lua
At the beginning of the script, you can see how to read the header of the file.
Probably, you can just copy from the start of script to the line "Datalenght = data_ChunkDataSize//blockalign" - and it will work.
__________________
ReaScripts
eugen2777 is offline   Reply With Quote
Old 06-15-2018, 06:55 AM   #11
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

@XRaym
You can find all C++-only functions also in my API-docs
http://www.mespotine.de/Ultraschall/Reaper-Api.html so you don't need to dig through the reaper_plugin.h
Meo-Ada Mespotine is offline   Reply With Quote
Old 06-15-2018, 07:13 AM   #12
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@eugen2777
Hi eugen, glad to see you, it's been a while !


Thanks the code !

LuaWAVE shows how to decode BitsPerSample info but the code is under copyright.

Your code is open source so it is all good !

Here is a code snippet extracted form your Sample Editor:


Code:
local Wave = {} -- Main table
-------------------------
-------------------------
-------------------------
function Wave:Get_SourceBitPerSamples()
   local Item, Take, Source, Source_type
      ------------------------------------------------------------------
      Item = reaper.GetSelectedMediaItem(0, 0)
      if Item   then Take = reaper.GetActiveTake(Item) else  return "No Selected Items!"  end 
      if Take   then Source = reaper.GetMediaItemTake_Source(Take) else  return "Empty item!" end
      if Source then Source_type = reaper.GetMediaSourceType(Source,"") end
      ------------------------------------------------------------------
      if Source_type~="WAVE" then return "Invalide Type - "..Source_type end
        
      ------------------------------------------------------------------
      -- Read data from wav file ---------------------------------------
      ------------------------------------------------------------------
      local FilePath  = reaper.GetMediaSourceFileName(Source , "")  -- Source FilePath
      local file = io.open(FilePath,"rb")                           -- open file, rb mode
      if not file then return "File not available!" end             -- if not available 
      
      --------------------------------------------------------
      -- RIFF ------------------------------------------------
      --------------------------------------------------------
      local Data = file:read(12)       -- read(12)
      ----------
      local RIFF_ChunkID, RIFF_chunkSize, RIFF_Type
      RIFF_ChunkID,                    -- "RIFF"
      RIFF_chunkSize,                  -- FileSize - 8
      RIFF_Type   =                    -- Source Type(for WAV = "WAVE")
      string.unpack("<c4 I4 c4",Data)  -------------------------------->>>> unpack
        --- FileSize ---------------------
        local FileSize = RIFF_chunkSize+8
        --- find "fmt ","data" section ---
        local find_lim = math.min(FileSize,1024^2)
        file:seek("set")
        Data = file:read(find_lim)
        local start_fmt  = Data:find("fmt ")
        local start_data = Data:find("data")
        ----------------------------------
        if not start_fmt or not start_data then return "'data' or 'fmt ' not found !" end
        if start_fmt>start_data then return "Section 'data' before section 'fmt ' !" end 
        
        -------------------------------------
        -- "fmt ", "data" sub-chunks --------
        -------------------------------------        
        ---- fmt ----
        file:seek("set", start_fmt-1)  -- set position
        Data = file:read(24)           -- read(24)
        local fmt_ChunkID, fmt_ChunkDataSize, audioFormat, nchans, srate, byterate, blockalign, bitspersample
        fmt_ChunkID,                   -- "fmt "
        fmt_ChunkDataSize,             -- fmt Size (16 for pcm)
        audioFormat,                   -- Compression_code(1 or 3 need)
        nchans,                        -- Number_of_channels
        srate,                         -- Sample_rate
        byterate,                      -- Averagebytes_per_second
        blockalign,                    -- block_align
        bitspersample =                -- Significant_bits_per_sample
        string.unpack("< c4 I4 I2 I2 I4 I4 I2 I2", Data)  ------------->>>> unpack
        return bitspersample
end

item = reaper.GetSelectedMediaItem(0,0)
if item then
  take = reaper.GetActiveTake(item,0)
  if take and not reaper.TakeIsMIDI(take) then
    source = reaper.GetMediaItemTake_Source(take)
    bit_depth = Wave:Get_SourceBitPerSamples()
  end
end

This works on wav file. It return the bit per samples as expected, in a more concize way than calling BWFMetaEdit :P

Ultimately, Xenakios solution will be the most efficient, of course, but meanwhile, this will help!

@mesopotine
Oh good ! But I dont think GetBitsPerSample isn't present on your doc, maybe it was ommited ? :S
X-Raym is offline   Reply With Quote
Old 06-15-2018, 07:20 AM   #13
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

Ok, I also looked at the this code.
https://github.com/Youka/LuaWAV/blob/master/wav.lua#L21
This will work slowly, I'm pretty sure, but I do not want to do the test.
Probably, many useful functions in Lua appeared later and there was no alternative.
Now we can use very simple and fast functions for pack/unpack and write/read data.
This makes it possible to work with tens, hundreds of megabytes without any problems.
__________________
ReaScripts
eugen2777 is offline   Reply With Quote
Old 06-15-2018, 07:37 AM   #14
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Indeed, your code is very efficient. I can work from it Thanks !
X-Raym is offline   Reply With Quote
Old 06-15-2018, 07:37 AM   #15
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

X-Raym, I think it's quite possible to deal with other formats, the main thing is to have information about the structure. But .... it's a long time, even more so if there are ready solutions.
__________________
ReaScripts
eugen2777 is offline   Reply With Quote
Old 06-15-2018, 07:39 AM   #16
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Don't worry, it is not needed for now. As I said to xenakios, my check bit depth function is the last check of a series of checks, and at this point of the function, it already knows it is a Wav file.


We'll refocus on that if new needs emerge (like Flac support if the C++ function doesn't support it).
X-Raym is offline   Reply With Quote
Old 06-15-2018, 07:56 AM   #17
eugen2777
Human being with feelings
 
eugen2777's Avatar
 
Join Date: Aug 2012
Posts: 271
Default

OK good luck!
PS. Interesting topic with markers. Do you use Python?
Just for information - you can edit markers, regions, etc. from Lua, and EEL. Of course, you have to write everything yourself.
It's funny, but I have a piece of code for adding / removing markers directly from Lua, in a very embryonic state (even worse than my other codes), but it works
Once again, good luck to you!
__________________
ReaScripts

Last edited by eugen2777; 06-15-2018 at 08:15 AM.
eugen2777 is offline   Reply With Quote
Old 06-15-2018, 04:04 PM   #18
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@eugen2777
I used python cause I found some libraries to parse the marker data. It was not working properly but I finally after a lot of trial of error manage to make it works, and also supports other kind of metadata.



but know you show me that Lua could have similar function too (unpack etc) and could process file quickly,
Maybe for a better REAPER integration, it may be a good idea to re-do the whole script in pure Lua. It would be far more simple to install for the end user !


Also, I was interested by Pytho for Tkinter, but I found that for the end user, it is not that easy to setup cause you have to use beyond REAPER etc... seems like GFX is still the best way to do GUI for ReaScript.



we can talk about that on the dedicated thread. :P
X-Raym is offline   Reply With Quote
Old 06-16-2018, 02:54 AM   #19
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Cfillion proposed a SWS test build with the get bit depth function !


https://github.com/reaper-oss/sws/issues/1010


Very powerful, it works even with non wav files !!
X-Raym is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 03:52 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.