unable to get peak/rms/decay level

219 views
Skip to first unread message

night94

unread,
Jul 24, 2016, 4:50:13 AM7/24/16
to gstreamer-java
I am attempting to get the current volume level from a live audio stream, using gstreamer 1.0.


Using the following command line:

gst-launch-1.0 -m audiotestsrc ! level ! fakesink

the messages from the level element read "rms=(GValueArray)NULL" (the same for peak and decay).

The same command using version 0.10 will in fact show the values. There was a ticket opened about that here:


and it was closed later stating that the values are in fact in the messages, just not deserialized to a display string.


Trusting that it is true, I am trying to read those values using gst1-java-core, which I understand is the most current version of the java bindings, working with the most current gstreamer. Here is the code:

public static void main(String[] args) {
        Gst.init();

        Pipeline pipeline = new Pipeline("pipeline");

        Element src = ElementFactory.make("audiotestsrc", null);
        Element audioConvert = ElementFactory.make("audioconvert", null);
        Element level = ElementFactory.make("level", null);
        level.set("message", "TRUE");
        Element fakesink = ElementFactory.make("fakesink", null);
        fakesink.set("sync", "TRUE");

        pipeline.addMany(src, audioConvert, level, fakesink);

        src.link(audioConvert);
        audioConvert.link(level);
        level.link(fakesink);

        Bus bus = pipeline.getBus();

        bus.connect(new Bus.MESSAGE() {

            public void busMessage(Bus bus, Message message) {
                if (message.getType() == MessageType.ELEMENT) {
                    Structure struct = message.getStructure();
                    System.out.println(struct);

                    ValueList lst = struct.getValueList("peak");

                    int numValues = lst.getSize();
                    System.out.println(numValues);

                    try {
                        double d = struct.getDouble("peak", 0);
                    } catch (Exception ex) {
                        System.out.println(ex);
                    }

                }
            }

        });


        pipeline.setState(State.PLAYING);

        Gst.main();
}


the println(struct) output is just like the command line message:

level, endtime=(guint64)23600000000, timestamp=(guint64)23500000000, stream-time=(guint64)23500000000, running-time=(guint64)23500000000, duration=(guint64)100000000, rms=(GValueArray)NULL, peak=(GValueArray)NULL, decay=(GValueArray)NULL;



lst.getSize()  will produce an assertion error, and the result is zero:

(unknown:17832): GStreamer-CRITICAL **: gst_value_list_get_size: assertion 'GST_VALUE_HOLDS_LIST (value)' failed


struct.getDouble("peak", 0) will produce another assertion, and then throw an exception:

(unknown:18056): GStreamer-CRITICAL **: gst_value_list_get_value: assertion 'GST_VALUE_HOLDS_LIST (value)' failed
java.lang.RuntimeException: List does not contain value 0

I tried also other types besides double, but never get any results. 


Is there no level? or am I doing something wrong here? I can't seem to find any further information online. I tried to run the example program "level-example.c", but I am having a hard time linking it.

If anyone has any more insight it would be greatly appreciated !


Neil C Smith

unread,
Jul 24, 2016, 5:16:12 AM7/24/16
to gstream...@googlegroups.com
Hi,

As of 1.0, GStreamer returns a GValueArray for those values, not a
GstValueList. Unfortunately, there's no higher-level mapping for that
yet, although GValue.GValueArray seems to exist.

What type of Object does struct.getValue("peak") give you? If it
gives you either the lowlevel structure or a Pointer (from which you
can create the lowlevel structure) you might be able to work around
this.

Best wishes,

Neil
> --
> You received this message because you are subscribed to the Google Groups
> "gstreamer-java" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to gstreamer-jav...@googlegroups.com.
> To post to this group, send email to gstream...@googlegroups.com.
> Visit this group at https://groups.google.com/group/gstreamer-java.
> For more options, visit https://groups.google.com/d/optout.



--
Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

Praxis LIVE - hybrid visual IDE for creative coding - www.praxislive.org
Digital Prisoners - interactive spaces and projections -
www.digitalprisoners.co.uk

night94

unread,
Jul 25, 2016, 4:09:38 PM7/25/16
to gstreamer-java
struct.getValue("peak") returns null.

If I trace into the getValue function, I see that gst.gst_structure_get_value() is called, and it returns a GValue object. Then getValue() is called on the GValue object and returned from that function (this is in Structure.java). val.getValue returns null. Why? Because the value field in GType contains some ungodly high number that doesn't seem to map to any of the types it attempts in GValueAPI.getValue(). 

night94

unread,
Jul 25, 2016, 4:33:17 PM7/25/16
to gstreamer-java
looks like I can get the value array when doing this:

        GValueAPI.GValue val = gst.gst_structure_get_value(this, fieldName);
        Pointer p = GVALUE_API.g_value_get_boxed(val);
        GValueAPI.GValueArray va = new GValueAPI.GValueArray(p);

flo

unread,
Aug 7, 2017, 6:22:02 AM8/7/17
to gstreamer-java
Hi night94,

I am facing the same problem you described in this thread. I wanted to solve it by using the three lines of code you posted above. Unfortunately it does not work on my end. Which context or namespace are you addressing with the "gst."-prefix? As far as I know the "gst."-prefix is used at the C-level. Did you build some kind of bypass and compiled gstreamer yourself in order to get the data? Is there a way to get the GValueArray on java-level?

Your help is really appreciated.

Many thanks in advance and best regards,

flo

Neil C Smith

unread,
Aug 7, 2017, 6:54:08 AM8/7/17
to gstream...@googlegroups.com
Hi,

On Mon, Aug 7, 2017 at 11:22 AM flo <flo...@gmail.com> wrote:
I am facing the same problem you described in this thread. I wanted to solve it by using the three lines of code you posted above. Unfortunately it does not work on my end. Which context or namespace are you addressing with the "gst."-prefix? As far as I know the "gst."-prefix is used at the C-level. Did you build some kind of bypass and compiled gstreamer yourself in order to get the data? Is there a way to get the GValueArray on java-level?


Does struct.getValue("peak") still return null?  I would have thought this might work since Christophe's changes for DecodeBin?  Still, this is going to change again in the near future.

The code changes posted earlier seem to have been made in Structure.  Note that the gst field is no longer inside Structure - it is replaced by GSTSTRUCTURE_API.  All the gst_* methods are in interfaces inside the lowlevel package - JNA maps to C functions by name, hence the C-like API in there.

Best wishes,

Neil
--
Neil C Smith
Artist & Technologist

flo

unread,
Aug 9, 2017, 2:44:32 PM8/9/17
to gstreamer-java
Hi Neil, 

thanks for your fast response. When printing the whole structure as a string, the peak-field says that it is null. However, using the command "GstStructureAPI.GSTSTRUCTURE_API.gst_structure_get_value(structure, "peak");" I was able to retreive a valid pointer. So basically I just had to replace the "gst."-prefix with your suggestion. Afterwards I was able to use the code of night94.

Everything seems to work properly now. Thank you very much for your help, it is really appreciated.


Regards,

Flo
Reply all
Reply to author
Forward
0 new messages