This discussion is archived
6 Replies Latest reply: Mar 23, 2011 2:54 PM by 845492 RSS

Is there no way to direclty find the "owning" mixer of a line?

845492 Newbie
Currently Being Moderated
While coding classes dealing with sound capture/playback, I've found it is often the case that I have a Line (Port, DataLine) and need to find the Mixer that this Line is associated with. Searching the API listing, forums, and other sources has yielded no direct way to traverse from a Line to a Mixer. Here's what I'd like to have:

Mixer AudioSystem.getMixerOwningLine(Line ownedLine);

or something like that. Of course, a Mixer is a Line also, and passing a Mixer to this method would be nonsensical. What I end up doing is this:
Mixer hackedGetMixerOwningLine(Line ownedLine) {
    Line.Info ownedLineInfo = ownedLine.getLineInfo();
    Mixer.Info[] mixerInfoArray = AudioSystem.getMixerInfo();
    for (Mixer.Info mixerInfo : mixerInfoArray ) {
        Mixer mixer = AudioSystem.getMixer(mixerInfo);
        if (mixer!=null && mixer.isLineSupported(ownedLineInfo)) {
            try {
                if (mixer.getLine(ownedLineInfo)==ownedLine) {
                    return mixer;
                }
            } catch (LineUnavailableException ex) {
                // No problem, continue
            }
        }
    }
    return null;
}
This seems to work... but is it really necessary? Thanks.
  • 1. Re: Is there no way to direclty find the "owning" mixer of a line?
    captfoss Pro
    Currently Being Moderated
    This seems to work...
    I think that code will only work in the case that a given mixer only supports one line that matches "ownedLineInfo".

    If it supports two or more of them, there's no guarantee that the line returned by getLine will be the one you want...
    but is it really necessary? Thanks.
    The convention I've always seen is, if you care about what mixer a line comes from, rather than using AudioSystem.getLines(blah blah), you iterate through all of the Mixers on the system and call getLines on them individually to build your list of lines.

    Essentially, rather than doing what you're doing on the backend, do it on the front end. Iterate through the mixers to get all of the associated lines of the type you're looking for, and then let the user pick from that list... and then you'll know which mixer it came from because you'll have gotten it directly from the mixer.
  • 2. Re: Is there no way to direclty find the "owning" mixer of a line?
    845492 Newbie
    Currently Being Moderated
    captfoss wrote:
    This seems to work...
    I think that code will only work in the case that a given mixer only supports one line that matches "ownedLineInfo".

    If it supports two or more of them, there's no guarantee that the line returned by getLine will be the one you want...
    I don't have enough different hardware at hand to test this thoroughly enough to state for certain that it works as intended, but the key is that once I find a Mixer that returns a line that matches the Line.Info passed in, I get the Line described by the Line.Info object and compare it to the Line argument passed in. If it's not the same, keep looking.
                    if (mixer.getLine(ownedLineInfo)==ownedLine) {
                        return mixer;
                    }
    However, you're getting right to the issue that I'm trying to figure out. I'm trying to decompose the larger issue into smaller ones so I'm not posting huge long questions that will take too long to read and absorb. Trying to be a courteous requester. Let me see if I can provide a concise summary of what I'm ultimately trying to do (with what seems to be an unusual system configuration - but I'd rather battle with it locally during development than remotely after deployment):

    I want to present users with a list of all source Ports found on the system to allow selection of any audio source available. I'd like to make this generic so that it isn't relying on naming or other common conventions that are not "guaranteed" platform-independent by the API and documentation. So I'm avoiding querying for any Mixers or source Ports based on name. (My system has source Ports with names that are really generic - and not even unique between unique Ports!)

    I started out by querying the system with:
      Line.Info[] sourcePortInfoAr = AudioSystem.getSourceLineInfo(new Line.Info(Port.class));
    and found that I did indeed get a Line.Info object for each unique source Port. However, as I said above, the Ports do not have unique names, an apparently the name, type and "direction" (source|target) are all that the Line.Info object contains. So if I have just a Line.Info returned by AudioSystem, how can I be sure to get the Line that was meant to be represented by the Line.Info returned by the AudioSytem call? [Note: I've verified that although these Ports do have the same name, they are unique. Through trial-and-error, I've seen that I can modify their associated VOLUME controls and have different audio input volume levels affected.]

    My current workaround is as you've suggested: iterate all Mixers, find all source Ports, and then work from there. Still, I've found many situations where I've had a Line and would like to acquire it's Mixer, but cannot.

    Thanks.
  • 3. Re: Is there no way to direclty find the "owning" mixer of a line?
    captfoss Pro
    Currently Being Moderated
    ags wrote:
    the key is that once I find a Mixer that returns a line that matches the Line.Info passed in, I get the Line described by the Line.Info object and compare it to the Line argument passed in. If it's not the same, keep looking.
    I don't think you're understanding why I'm saying that's a bad idea.

    Let's say you go into a store and ask the cashier if he has a 5 dollar bill. You're looking for a specific 5 dollar bill, you know its serial number. He opens the register, he has a give dollar bill so he lets you look at it. Turns out it's not the one you're looking for, so you leave.

    What's the problem here? You didn't look through all of his 5 dollar bills... maybe he had the one you're looking for, but it wasn't at the top of his stack...

    So, if a Mixer has multiple lines of the same type, it's only going to give you the line on top if you're using getLine(ownedLineInfo)... so it may have the line you want, but it might never give it to you.

    You should instead ask the store owner to see all of his 5 dollars bills, and iterate through all of the lines on the Mixer by using getSourceLines and getTargetLines...
  • 4. Re: Is there no way to direclty find the "owning" mixer of a line?
    845492 Newbie
    Currently Being Moderated
    captfoss wrote:
    I don't think you're understanding why I'm saying that's a bad idea.

    Let's say you go into a store...
    You should instead ask the store owner to see all of his 5 dollars bills, and iterate through all of the lines on the Mixer by using getSourceLines and getTargetLines...
    Yes, that analogy is very clear. It's the difference between looking for an object of a certain class vs. looking for a certain instance of an object (of a certain class).

    I am currently doing just what you suggest: I iterate over all Mixers (found by using the AudioSystem.getMixerInfo() method) and then iterate over all Lines on each Mixer that are source Lines of class "Port".

    Perhaps I'm now being too "fussy" about the strange ways that the hardware can be represented through the java.sound API (driven by the very odd way my particular hardware's sound system is reported) - but my concern with this method is that if there is a single source Port that for some bizarre reason is attached to more than one Mixer, I will then be "finding" multiple (apparent) instances of a source Port but in fact they will be duplicates. I'd like to say that "this could never happen" but I've seen that my system reports things that I'd also thought couldn't happen (e.g. different ports on different mixers having the exact same name). My attempt at directly querying the AudioSystem for all source Port objects was in the hopes that if individual Ports did in fact exist on multiple Mixers, the all-knowing AudioSystem would be smart (and kind) enough to report back only the unique source Ports.

    As an aside, is my understanding correct that there is no direct way to traverse a parent/child relationship between a (child) Port/DataLine and it's associated (parent) Mixer? I see no way of doing this based on the java.sound.sampled API.

    Thanks.
  • 5. Re: Is there no way to direclty find the "owning" mixer of a line?
    captfoss Pro
    Currently Being Moderated
    I am currently doing just what you suggest: I iterate over all Mixers (found by using the AudioSystem.getMixerInfo() method) and then iterate over all Lines on each Mixer that are source Lines of class "Port".
    Ok... that's not what your code above does, but I guess you've changed it.
    Perhaps I'm now being too "fussy" about the strange ways that the hardware can be represented through the java.sound API (driven by the very odd way my particular hardware's sound system is reported) - but my concern with this method is that if there is a single source Port that for some bizarre reason is attached to more than one Mixer, I will then be "finding" multiple (apparent) instances of a source Port but in fact they will be duplicates. I'd like to say that "this could never happen" but I've seen that my system reports things that I'd also thought couldn't happen (e.g. different ports on different mixers having the exact same name). My attempt at directly querying the AudioSystem for all source Port objects was in the hopes that if individual Ports did in fact exist on multiple Mixers, the all-knowing AudioSystem would be smart (and kind) enough to report back only the unique source Ports.
    Ummmm, there's no reason that I'm aware of a source port wouldn't feed into multiple mixers... if it was something like "CD AUDIO" then I'd kind of expect it to feed into all of the mixers...or at least some of them.
    As an aside, is my understanding correct that there is no direct way to traverse a parent/child relationship between a (child) Port/DataLine and it's associated (parent) Mixer? I see no way of doing this based on the java.sound.sampled API.
    Trying to find the "owner" of a line would be like trying to find the "owner" of an IP socket. There is no owner, just whatever objects have references to it...

    There is no relationship between a mixer, source lines, or data lines... they are all separate entities. The mixer just reads from or writes to these lines it keeps a list of... doesn't make it the owner of the lines, doesn't make it the parent of child of the lines... it just makes it a user of the lines.

    You're trying to impose the structure you know is present in the hardware upon its representation in software. There's no guarantee that a SourceLine goes into a single mixer. It could be stereo input that feeds into a left mixer and a right mixer. It almost certainly isn't, but, there's no guarantee that it isn't... I could fairly easily implement such a creature.

    You could also have a port that doesn't go into / come out of a Mixer... don't know why you ever would, but again... JavaSound is a giant bag of cooked spagetti. It's just datalines going wherever they want.
  • 6. Re: Is there no way to direclty find the "owning" mixer of a line?
    845492 Newbie
    Currently Being Moderated
    Yes, I did change the code along the way.

    You are correct that I am projecting my understanding of the underlying hardware onto the logical model presented by java.sound. I did look very carefully at the entire (sound) API and didn't see a way to traverse what I thought was a basic relationship (Line->Mixer) before posting, but hoped I had somehow missed something. Very similar to my other recent poast about "logical connections" between mixers - only identifyable through similar mixer names. I thought that couldn't possibly be correct.

    Thanks for taking the time to disabuse me of my incorrect notion of how java.sound presents an interface to the hardware. I understand that while java tries to present a simple, logical, consistent model of the hardware, the variation of sound cards across machines is huge and it is a very complex task.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points