Announcement

Collapse
No announcement yet.

Select sound card problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Select sound card problem

    I am trying to select a sound card to use and the output keeps going to my default card and not the one I select. This is a very brief program showing the problem. How to do this?
    Code:
    #PBFORMS CREATED V1.51
    '------------------------------------------------------------------------------
    ' The first line in this file is a PB/Forms metastatement.
    ' It should ALWAYS be the first line of the file. Other
    ' PB/Forms metastatements are placed at the beginning and
    ' end of "Named Blocks" of code that should be edited
    ' with PBForms only. Do not manually edit or delete these
    ' metastatements or PB/Forms will not be able to reread
    ' the file correctly.  See the PB/Forms documentation for
    ' more information.
    ' Named blocks begin like this:    #PBFORMS BEGIN ...
    ' Named blocks end like this:      #PBFORMS END ...
    ' Other PB/Forms metastatements such as:
    '     #PBFORMS DECLARATIONS
    ' are used by PB/Forms to insert additional code.
    ' Feel free to make changes anywhere else in the file.
    '------------------------------------------------------------------------------
    
    #COMPILE EXE
    #DIM ALL
    
    '------------------------------------------------------------------------------
    '   ** Includes **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN INCLUDES
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #PBFORMS END INCLUDES
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Constants **
    '------------------------------------------------------------------------------
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1   =  101
    %IDC_COMBOBOX1 = 1001
    %IDC_BUTTON1   = 1002
    %IDC_BUTTON2   = 1003
    %IDC_LABEL1    = 1004
    #PBFORMS END CONSTANTS
    '------------------------------------------------------------------------------
    $MUSICFILE = "American Pie.mp3"  '<----Name your music file here
    '------------------------------------------------------------------------------
    '   ** Declarations **
    '------------------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS _
               LONG, BYVAL  lCount AS LONG) AS LONG
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    '------------------------------------------------------------------------------
    GLOBAL soundcards()AS STRING
    '------------------------------------------------------------------------------
    '   ** Main Application Entry Point **
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION GetSoundCards() AS LONG
        LOCAL hr,i AS LONG
        LOCAL woc AS WAVEOUTCAPS
        
        REDIM SoundCards(1:WaveOutGetNumDevs)
        
        FOR i = 0 TO WaveOutGetNumDevs -1
            hr = waveOutGetDevCaps(i,woc,SIZEOF(woc))
            Soundcards(i+1)=woc.szPName
        NEXT
        FUNCTION = UBOUND(soundcards)
    END FUNCTION
    
    '------------------------------------------------------------------------------
    '   ** CallBacks **
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
    STATIC soundcard AS STRING
    LOCAL i   AS LONG
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                i = getSoundCards
                SampleComboBox CB.HNDL, %IDC_COMBOBOX1, i
                COMBOBOX SELECT CB.HNDL,%idc_Combobox1,1
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_COMMAND
                ' Process control notifications
                SELECT CASE AS LONG CBCTL
                    CASE %IDC_COMBOBOX1
                          IF CB.CTLMSG = %CBN_SELENDOK THEN
                              COMBOBOX GET TEXT CB.HNDL, %IDC_COMBOBOX1 TO _
                                                          soundcard
                          END IF
                    CASE %IDC_BUTTON1
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            'play using selected sound card
                            LOCAL audiodevice AS ASCIIZ * 200
                            LOCAL le AS LONG
                            COMBOBOX GET TEXT CB.HNDL,%IDC_Combobox1 TO _ 
                                                    AudioDevice
                           le = mcisendstring("open " + $DQ + $MusicFile + _
                                                    $DQ ,AudioDevice,0,0)
                           le = mcisendstring("play " + $DQ + $MusicFile + $DQ,"",0,0)
                        END IF
    
                    CASE %IDC_BUTTON2
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                            DIALOG END CB.HNDL
                        END IF
    
                    CASE %IDC_LABEL1
    
                END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Sample Code **
    '------------------------------------------------------------------------------
    FUNCTION SampleComboBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount _
        AS LONG) AS LONG
        LOCAL i AS LONG
    
        CONTROL SEND hDlg, lID, %CB_SETEXTENDEDUI, %TRUE, 0
    
        FOR i = 1 TO lCount
            COMBOBOX ADD hDlg, lID, Soundcards(i)
        NEXT i
    END FUNCTION
    '------------------------------------------------------------------------------
    
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "Dialog1", 199, 160, 201, 121, TO hDlg
        CONTROL ADD COMBOBOX, hDlg, %IDC_COMBOBOX1, , 40, 65, 100, 40
        CONTROL ADD BUTTON,   hDlg, %IDC_BUTTON1, "Play", 65, 15, 50, 15
        CONTROL ADD BUTTON,   hDlg, %IDC_BUTTON2, "E&xit", 140, 95, 50, 15
        CONTROL ADD LABEL,    hDlg, %IDC_LABEL1, "Select Sound Card", 40, 55, _
            100, 10
    #PBFORMS END DIALOG
    
        
    
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    Barry

  • #2
    Deja Vu all over again?

    http://www.powerbasic.com/support/pb...ght=sound+card

    Unfortunately there does not appear to be a "this works" answer posted. (Yet?)
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Nope. Nothing posted yet and google doen't find anything but "look here" and it goes from there. It was in MS's library where I found the example to use the sound card name in the open statement. That playes it but always at the default card.
      http://msdn.microsoft.com/en-us/libr...76(VS.85).aspx
      Last edited by Barry Erick; 4 Jul 2009, 04:25 PM. Reason: Added link
      Barry

      Comment


      • #4
        Code:
        Soundcards(i+1)=[B]woc.szPName[/B]
        ....
        COMBOBOX ADD hDlg, lID, Soundcards(i)
        ...
        COMBOBOX GET TEXT CB.HNDL,%IDC_Combobox1 TO _ 
                                                        AudioDevice
        
        ...
        Are you sure this is the same as....
        Identifier of an MCI device or device driver. This can be either a device name (as given in the registry or the SYSTEM.INI file) or the filename of the device driver. If you specify the filename of the device driver, you can optionally include the .DRV extension, but you should not include the path to the file.
        ???
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          I did search the registry and the name is the same. I did see something on another site saying MCI can't change|select the sound card. But the MS link sure makes it sound that way. I have so much mci code in there that I would be breaking the entire program to change to another way of doing it. I wonder if I save the device and then change it back on program exit, if I could keep it. Problem is, this program has to play different things overlapping on different sound cards, if available. Everything is working and this was the last thing to do.....
          Barry

          Comment


          • #6
            One would think this is rather easy, as many programs can do this. Now, I can't shell out to set this, as this project is a playback device that plays selections on the same or different sound cards. A cue channel might be on one card and the program another. Or individual program channels will go out on different sound cards, so the output is on the fly and not any other way. Googling this brings up many unanswered questions or comments like use directx or this other program library. Think is, I'm not shelling out hundreds of dollars just for this function. One way is to change the setting in the registry but that only works in xp and is not a very nice way to go. I don't want to change the preferred, I just want to use (specify) another sound card at times. If I have to change to something other than MCI, I will, but i need to play and control mp3, wav, broadcast wav, wma files (which I do with mci), get their format information (from my own library) and select what sound card plays them.

            It seems, among all the programmers in this forum, that no one knows how.
            Barry

            Comment


            • #7
              Barry,
              Code:
              le = mcisendstring("open " + $DQ + $MusicFile + _
                                                              $DQ ,AudioDevice,0,0)
              Is "AudioDevice" not in the wrong place?
              For mciSendString there are 4 parameters
              1) the string you send (which includes everything, including the audio device if needed)
              2) the return string
              3) the length of the return string
              4) a flag to say which callback might be needed.

              You have AudioDevice in the return string position.
              I can't test it because I don't have multiple audio cards but you probably need something more like this:
              Code:
              le = mcisendstring("open " + $DQ + $MusicFile + _
                                                              $DQ +" "+AudioDevice,"",0,0)
              Paul.
              Last edited by Paul Dixon; 7 Jul 2009, 11:19 AM. Reason: Inserted a space before "AudioDevice"

              Comment


              • #8
                > Is "AudioDevice" not in the wrong place...

                Nice catch.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Does not work at all in the example. All I have found in searching says MCI can't change and the only parameter selecting a sound card is the device that plays the item wanted.. ie: WAVE or video, etc. Not card. With MCI you have to change the registry. I am doing it that way now... and it works. I hate doing it that way, but I first get the value at:

                  HKEY_CURRENT_USER,Software\Microsoft\Multimedia\Sound Mapper,Playback

                  and save it. Then I change that to the sound card I want and then restore the original value on the exit.

                  I still have to see if this works in a limited account. I know it does not work in Vista, but that OS is a no-no for this program, anyway. I will see that it runs in XP Mode on windows7 in the fall. This allows me to set the NEXT sound card to use when the Next OPEN statement shows.
                  Barry

                  Comment


                  • #10
                    Well the registry thing almost works. I had this in following the change to confirm it changed:

                    Code:
                    SHELL "rundll32.EXE shell32.DLL,Control_RunDLL mmsys.cpl,,2 "
                    And it worked if I clicked ok. It did not work without this in there, so I am trying find out how mmsys.cpl closes that closing the reg flush or close does not do. Or how to silently (not show) mmsys.cpl and do an ok. The only other way I've found is by using low level waveout messages, but they only work on wave and not mp3 stuff. Now, I could purchace an expensive library, but I do not want to go there.
                    Barry

                    Comment


                    • #11
                      RegSetValueEx()

                      ????

                      OR..

                      You may have to broadcast a WM_SYSINICHANGE message to get existing programs to recognize that some default thing has changed.. but I would like to think the control panel applet does that if necessary.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        RegChangeex... not sure if I am doing that. Why not? Well, back in 02 I wrote a registry change program for my first dll. I can't find the source, only the inc file and dll. I used that. I still have a few cd's to look at.

                        I will try the WM_SYSINICHANGE message, as the windows applet works....
                        Last edited by Barry Erick; 11 Jul 2009, 12:54 PM.
                        Barry

                        Comment


                        • #13
                          PB uses the %WM_SETTINGCHANGE instead, but that did not work, unless I need some parameters. I tried dialog send cb.hndl, %WM_SETTINGCHANGE,0,0
                          Barry

                          Comment


                          • #14
                            I found a workaround......

                            http://www.codeproject.com/KB/system...select=2848723
                            Barry

                            Comment


                            • #15
                              > I tried dialog send cb.hndl, %WM_SETTINGCHANGE,0,0

                              NOt that its crucial right now because you have found something (which the author himself describes as a "kludge") but...

                              When you change a system setting, you have to BROADCAST the message to all top-level windows:
                              Code:
                              SendMessage  %HWND_BROADCAST, msgId, wPAram, lParam
                              FWIW...re which message to broadcast....

                              WM_WININICHANGE

                              An application sends the WM_WININICHANGE message to all top-level windows after making a change to the WIN.INI file. The SystemParametersInfo function sends this message after an application uses the function to change a setting in WIN.INI.

                              Note The WM_WININICHANGE message is provided only for compatibility with earlier versions of the system. Applications should use the WM_SETTINGCHANGE message.
                              MCM
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                The link I showed works but is not acceptable. I can't show a flash of the sounds and Audio Devices Properties window on the change.

                                On using the registry way, the
                                sendmessage %HWND_BROADCAST,%WM_SETTINGCHANGE,0,0

                                works but it takes about 10 seconds to complete, which is not acceptable. I think it needs the correct parameters. I have tried several and the fast ones are wrong, as they don't work.
                                Barry

                                Comment


                                • #17
                                  Seeing how hard this is to do, I am changing my way. This progrect has two programs, one to maintain the db and the other to use it and they will run on different PC's. On the first, which I am currently running into this sound card issue, I will simply use the "Sounds and Audio Devices Properties" dialog (mmsys.cpl). For the main program, I will do it in two versions. One with just one card and the other will be using BASS.DLL, which will be costlier since the license will carry. (They state the sound card change is done in a context switching mode and I see they have a patent on that process.) I know I will try to figure out what context switching is.. I suppose it has to do with getting the driver used and simply switching drivers while maintaining the same device name. (I have not read the patent...)
                                  Barry

                                  Comment

                                  Working...
                                  X