Beginner type questions


#1

I’ve just started poking around having a play with Juce.

Have to say it’s a truly amazing piece of work. It’s as though somebody was behind me listening to all the things I didn’t like about MFC/C++ Builder/wxWindows etc, took those comments and then went further than I could have imagined in fixing them all and then some and then some more. Makes me feel very small indeed!

Just got a few piddly questions:

1:FilenameComponent - is that going to get the Juce treatment rather than the bloody 'orrible (in Windows anyway) native drectory browser.

2:I can’t (because I’m a newbie?) get what what on windows would be called a modeless dialog window. If I have a ResizableWindow set on the desktop my main window can be put in front of it (it also appears on the taskbar which I don’t really want). If I set it to stay on top, it also stays on top of other apps. If I set it’s Component to be my main window I can’t move it outside the main window even if I call setConstrainer(0).

3:If I’m playing audio I can’t get at AudioTransportSource.resamplerSource or related properties - I’d like to be able to varispeed on playback. Is the only way to do this to create a separate ResamplingAudioSource object? Also, any quality settings?

Thanks,
Pete Gates


#2

Welcome, and glad you like it. And if you’re any relation to Bill Gates, feel free to suggest he buys juce off me for a squillion dollars.

1 - you mean should it pop up a juce file chooser? I guess it could do, it’d just require a small tweak. Maybe could add it as an option

2 - not really sure what you’re after. Do you mean you want it just to stay in front of other juce windows? I’ve not got anything in place to do that at the moment, but on my to do list is something to enforce fixed z-orders between sets of windows

3 - if you’re trying to do fancy stuff you’ll need to create your own custom audio sources. There’d be nothing stopping you inserting another resampler in the output chain and adjusting that, or writing your own resampler object.


#3

Nah, unless he’s a very uncool uncle I’ve never been told about, the best I can do is buy the commercial license in a month or two, poor second best but there you go. They should have bought it for Vista though.

Yes, that one. Your ones just look so much nicer.

Yes, like floating tool windows, stay above my app but not everything else.

Fair enough, I suppose I have to do some work!

Other question is on SystemStats::getMACAddresses, it’s always returning 0 for me. in juce_win32_network.cpp it’s skipping (enums.length == 0):

    ncb.ncb_command = NCBENUM;
    ncb.ncb_buffer = (unsigned char*) &enums;
    ncb.ncb_length = sizeof (LANA_ENUM);
    NetbiosCall (&ncb);

    for (int i = 0; i < enums.length; ++i)

Sort of out of your control after that point I suppose but any insight would be welcome!

Thanks again,
Pete


#4

hmm - that is a bit odd if you’ve got a network card, but there’s not much you can do if it comes back saying there aren’t any cards. If you do an “ipconfig /all” does that report any mac addresses?


#5

Yep, 2 (ethernet and wireless) on my laptop. I’ve used the iphlpr stuff before on Windows with success though I assume the Netbios way works on everyone elses machine!

Couple of other questions. I’m doing a custom dialog box derived from DialogWindow with a content component from jucer. That all works fine up to a point. Firstly I’m initiating this by calling runModalLoop, is the correct way to exit to call exitmodalstate or calling setvisible(false) which I’ve seen in some of your code?

Also I’ve got some text editors in the dialog and I’ve got two questions about those: If they have the focus, Escape and Enter no longer close the dialog box, what’s the recommended way to enable this. I see in some code where you’ve used a subclass of Text Editor to pass those keystrokes up (which I’ve tried and failed with so far!) or is there another way? Also I want to set the focus to one of the editors when the dialog shows, grabkeyboardfocus seems to be doing nothing for me, I’ve called setwantskeyboardfocus(true) first but no joy. Is the dialog constructor too soon to be calling those functions? If so where??

Thanks for any help!
Pete


#6

Yep, 2 (ethernet and wireless) on my laptop. I’ve used the iphlpr stuff before on Windows with success though I assume the Netbios way works on everyone elses machine!

Couple of other questions. I’m doing a custom dialog box derived from DialogWindow with a content component from jucer. That all works fine up to a point. Firstly I’m initiating this by calling runModalLoop, is the correct way to exit to call exitmodalstate or calling setvisible(false) which I’ve seen in some of your code?

Also I’ve got some text editors in the dialog and I’ve got two questions about those: If they have the focus, Escape and Enter no longer close the dialog box, what’s the recommended way to enable this. I see in some code where you’ve used a subclass of Text Editor to pass those keystrokes up (which I’ve tried and failed with so far!) or is there another way? Also I want to set the focus to one of the editors when the dialog shows, grabkeyboardfocus seems to be doing nothing for me, I’ve called setwantskeyboardfocus(true) first but no joy. Is the dialog constructor too soon to be calling those functions? If so where??

Thanks for any help!
Pete[/quote]

I’ve never heard of iphlpr - have you got a link for it?

You can use exitModalState or setVisible (false) - either one will work. setVisible just calls exitmodalstate internally.

Yes, you could override the keypress method to pass-up the keys you don’t need. If it’s not working, it might just be that you’re not doing something right, as I use the same trick in a few places.

The constructor is too soon to do focus stuff, because the window won’t even exist yet. A quick trick that would work would be to post a message in the constructor with Component::postCommandMessage and set the focus when the message arrives.


#7

Look up GetIfTable in the Platform SDK docs I’m going to frame this as probably the one and only time I’m going to give
you some useful information!

Ta.

Oh yes, I’m sure it’s something I’m doing, I’ll keep on trying!

I thought so. At what point does a window exist fully? For example, I’m trying to set the focus after the content component is created and set as the content component in the constructor of my DialogWindow subclass. Is it because the content component isn’t really fully constructed or is it because the DialogWindow is mid-construction?

Thanks,
Pete


#8

[quote=“peteg”][quote=“jules”]
I’ve never heard of iphlpr - have you got a link for it?
[/quote]
Look up GetIfTable in the Platform SDK docs I’m going to frame this as probably the one and only time I’m going to give
you some useful information!

Ta.

Oh yes, I’m sure it’s something I’m doing, I’ll keep on trying!

I thought so. At what point does a window exist fully? For example, I’m trying to set the focus after the content component is created and set as the content component in the constructor of my DialogWindow subclass. Is it because the content component isn’t really fully constructed or is it because the DialogWindow is mid-construction?

Thanks,
Pete[/quote]

Ta for the tip, I’ll look that up.

The problem with focus will most likely be because your DialogWindow’s not yet on-screen. It’s an interesting question - maybe I should add some kind of mechanism that will defer focusing a component if it’s not yet there, so that you could write your original code and still have it work properly. I’ll have a think about that one…


#9

Out of interest, do you want to try this MAC address fix - both methods work on my machine, but I’d be interested to see if this gets it right on yours. It’s in juce_win32_Network.cpp:

[code]static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum)
{
int numFound = 0;

DynamicLibraryLoader dll (T("iphlpapi.dll"));
DynamicLibraryImport (GetAdaptersInfo, getAdaptersInfo, DWORD, dll, (PIP_ADAPTER_INFO, PULONG))

if (getAdaptersInfo != 0)
{
    ULONG len = sizeof (IP_ADAPTER_INFO);
    MemoryBlock mb;
    PIP_ADAPTER_INFO adapterInfo = (PIP_ADAPTER_INFO) mb.getData();

    if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
    {
        mb.setSize (len); 
        adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
    }

    if (getAdaptersInfo (adapterInfo, &len) == NO_ERROR)
    {
        PIP_ADAPTER_INFO adapter = adapterInfo;

        while (adapter != 0)
        {
            int64 mac = 0;
            for (unsigned int i = 0; i < adapter->AddressLength; ++i)
                mac = (mac << 8) | adapter->Address[i];

            if (numFound < maxNum && mac != 0)
                addresses [numFound++] = mac;

            adapter = adapter->Next;
        }
    }
}

return numFound;

}

static int getMACAddressesViaNetBios (int64* addresses, int maxNum)
{
int numFound = 0;

DynamicLibraryLoader dll (T("netapi32.dll"));
DynamicLibraryImport (Netbios, NetbiosCall, UCHAR, dll, (PNCB))

if (NetbiosCall != 0)
{
    NCB ncb;
    zerostruct (ncb);

    typedef struct _ASTAT_
    {
        ADAPTER_STATUS adapt;
        NAME_BUFFER    NameBuff [30];
    } ASTAT;

    ASTAT astat;
    zerostruct (astat);

    LANA_ENUM enums;
    zerostruct (enums);

    ncb.ncb_command = NCBENUM;
    ncb.ncb_buffer = (unsigned char*) &enums;
    ncb.ncb_length = sizeof (LANA_ENUM);
    NetbiosCall (&ncb);

    for (int i = 0; i < enums.length; ++i)
    {
        zerostruct (ncb);
        ncb.ncb_command = NCBRESET;
        ncb.ncb_lana_num = enums.lana[i];

        if (NetbiosCall (&ncb) == 0)
        {
            zerostruct (ncb);
            memcpy (ncb.ncb_callname, "*                   ", NCBNAMSZ);
            ncb.ncb_command = NCBASTAT;
            ncb.ncb_lana_num = enums.lana[i];

            ncb.ncb_buffer = (unsigned char*) &astat;
            ncb.ncb_length = sizeof (ASTAT);

            if (NetbiosCall (&ncb) == 0)
            {
                if (astat.adapt.adapter_type == 0xfe)
                {
                    int64 mac = 0;
                    for (unsigned int i = 0; i < 6; ++i)
                        mac = (mac << 8) | astat.adapt.adapter_address[i];

                    if (numFound < maxNum && mac != 0)
                        addresses [numFound++] = mac;
                }
            }
        }
    }
}

return numFound;

}

int SystemStats::getMACAddresses (int64* addresses, int maxNum)
{
int numFound = getMACAddressViaGetAdaptersInfo (addresses, maxNum);

if (numFound == 0)
    numFound = getMACAddressesViaNetBios (addresses, maxNum);

return numFound;

}[/code]


#10

[quote=“jules”]Out of interest, do you want to try this MAC address fix - both methods work on my machine, but I’d be interested to see if this gets it right on yours. It’s in juce_win32_Network.cpp:
[/quote]
Ta,
It’s missing the

#include <Iphlpapi.h>
#include “…/…/…/src/juce_core/containers/juce_MemoryBlock.h”

but I suppose you were just getting it to me in a hurry. Anyway, works fine, thanks!!

I sorted out the thing with escape/return keys in TextEditors, they were being passed up but the containing DialogWindow wasn’t doing anything with them - I’d assumed that was automatic.

Also I’m using a persistent DialogWindow that gets gets constructed at startup then shown when needed - I’m lazy, it has lots of settings I can’t be bothered about saving/loading each time. ExitModalState doesn’t seem to hide the dialog, I have to do a setvisible(false) manually, is that right? I need to use ExitModalState to confirm stuff.

In WavAudioFormat there seems to be a bug in reading BWAV coding history or I’m being thick, space never seems to be allocated on read, write’s are fine. Not the most used field but… Also I notice that you don’t seem to be using the full WAVEXTENSIBLE format for 24bit int 32bit float files, is there a reason for this? Also are you ever going to do an mp3 reader? I do need one and will do one but you’d do it better! Is it just the licensing?

Thanks yet again,
Pete


#11

[quote=“peteg”][quote=“jules”]Out of interest, do you want to try this MAC address fix - both methods work on my machine, but I’d be interested to see if this gets it right on yours. It’s in juce_win32_Network.cpp:
[/quote]
Ta,
It’s missing the

#include <Iphlpapi.h>
#include “…/…/…/src/juce_core/containers/juce_MemoryBlock.h”

but I suppose you were just getting it to me in a hurry. Anyway, works fine, thanks!!

I sorted out the thing with escape/return keys in TextEditors, they were being passed up but the containing DialogWindow wasn’t doing anything with them - I’d assumed that was automatic.

Also I’m using a persistent DialogWindow that gets gets constructed at startup then shown when needed - I’m lazy, it has lots of settings I can’t be bothered about saving/loading each time. ExitModalState doesn’t seem to hide the dialog, I have to do a setvisible(false) manually, is that right? I need to use ExitModalState to confirm stuff.

In WavAudioFormat there seems to be a bug in reading BWAV coding history or I’m being thick, space never seems to be allocated on read, write’s are fine. Not the most used field but… Also I notice that you don’t seem to be using the full WAVEXTENSIBLE format for 24bit int 32bit float files, is there a reason for this? Also are you ever going to do an mp3 reader? I do need one and will do one but you’d do it better! Is it just the licensing?

Thanks yet again,
Pete[/quote]

ah yes, forgot to mention the includes, but I see you’re on the case there.

The BWAV stuff looks fine to me - the struct itself is created with enough extra space for the coding history. Did you actually have a problem using it?

And I must admit I’d never heard of WAVEXTENSIBLE, but will do some research.

And yep, the problem with mp3 is the licensing. I’ve got some code here that’ll write mp3s using the lame encoder dll if it can find it, so I might tidy that up and add it to the library at some point. Reading mp3s is easy enough but I’m not sure about the legal ramifications.


#12

[quote]The BWAV stuff looks fine to me - the struct itself is created with enough extra space for the coding history. Did you actually have a problem using it?
[/quote]
Yes, it was only showing the first character of coding history on read. I’ll have another look at it now I’m finding my way around.

[quote]And I must admit I’d never heard of WAVEXTENSIBLE, but will do some research.
[/quote]
Lookup WAVEFORMATEXTENSIBLE in the Platform SDK, it adds some fields to WAVEFORMATEX for multichannel, lots of bits, stuff like that.

Cheers,
Pete


#13

You’re right, there’s a really dumb error in the bit that reads the chunk - try replacing this bit:

else if (chunkType == chunkName ("bext")) { // Broadcast-wav extension chunk.. BWAVChunk* const bwav = (BWAVChunk*) juce_calloc (length); input->read (bwav, length); bwav->copyTo (metadataValues); juce_free (bwav); }


#14

I’d suggest

If the BWAV doesn’t have a coding history (which is legal) the

could contain junk.The standard is vague here, some apps write a terminating null if there’s no coding history, some don’t. This gets round that.

Much, much more importantly:

Point me at it! (I didn’t read the second part of the sentence - it’s a failing I have)

Thanks,
Pete


#15

Ah yes, you spotted my deliberate mistake there…

What I meant was that writing an AudioFormatReader for mp3s would be straightforward, using libmpeg. I’ve not actually done one, though.


#16