Announcement

Collapse
No announcement yet.

Memory resident files

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

  • Memory resident files

    I'm making some progress in playing WAV files from PBDLL
    programs. The following program seems to work, except for
    the proper call to PLAYSOUND function when passing a copy
    of a file in a string, instead of the file name.

    Questions I have:

    1. Where can I find the documentation for the
    function PLAYSOUND. It works but is nowhere
    to be found in PDDLL HELP, or WIN32API.HLP.
    2. By experimentation I've found giving PLAYSOUND
    a file name that does not exist, e.g. "" causes
    sound to terminate. Does doing so mess up any
    memory structures that will cause me problems
    later. Or perhaps there is a documented legal
    way to stop sound from being played?
    3. I'd like to have the .WAV files in memory and
    pass them to the PLAYSOUND function. Is there
    a mechanism to create memory files and use a
    memory handle as if it were a file. I'd
    appreciate any references or examples that do this.

    Can anyone help me with calarification/info references?

    --------------------------------------------------------------
    ' In the program below Fname must be the path and file
    ' name for a .WAV file (or maybe other file types are
    ' accepted?
    --------------------------------------------------------------
    Code:
    #COMPILE EXE
    #REGISTER NONE
    $INCLUDE "WIN32API.INC"
    GLOBAL MemoryString AS STRING
    
    SUB PlayWave(Fn AS STRING)
    PlaySound BYCOPY Fn,BYVAL NULL%,%SND_ASYNC
    END SUB
    
    CALLBACK FUNCTION CBPlay:CALL PlayWave("1c-1.wav"):END FUNCTION
    CALLBACK FUNCTION CBStop:CALL PlayWave(""):END FUNCTION
    CALLBACK FUNCTION CBMem:CALL PlayWave(MemoryString):END FUNCTION
    
    FUNCTION PBMAIN() AS LONG
    LOCAL hDlg AS LONG
    LOCAL Fname AS STRING
    Fname="1c-1.wav"
    OPEN Fname FOR RANDOM AS #1:GET$ 1,LOF(1),MemoryString:CLOSE #1
    DIALOG NEW 0,"Play Wav",,,320,240,_
     %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
     %WS_MINIMIZEBOX OR %DS_CONTEXTHELP,0 TO hDlg
    IF hDlg=0 THEN EXIT FUNCTION  ' Error occurred
    CONTROL ADD BUTTON,hDlg,200,"Play "+Fname,130,60,60,20,0 CALL CBPlay()
    CONTROL ADD BUTTON,hDlg,201,"Play Memory Copy",130,100,100,20,0 CALL CBMem()
    CONTROL ADD BUTTON,hDlg,202,"Stop Playing",130,140,60,20,0 CALL CBStop()
    DIALOG SHOW MODAL hDlg
    END FUNCTION

  • #2
    I found information on RESOURCES in the PBCC forum and appended
    the logic to the program posted above. The "improved" program
    below compiles and executes without a GPF, but does not work.
    Any suggestions would be appreciated.

    Aloha,
    Joe Speroni
    Lawai, HI
    ---------------------------------------------------------------
    Code:
    #COMPILE EXE
    #REGISTER NONE
    $INCLUDE "WIN32API.INC"
    GLOBAL MemoryString AS STRING
    GLOBAL hMem AS LONG
    GLOBAL lpbi AS LONG
    
    SUB PlayWave(Fn AS STRING)
    PlaySound BYCOPY Fn,BYVAL NULL%,%SND_ASYNC
    END SUB
    
    CALLBACK FUNCTION CBPlay
    CALL PlayWave("1c-1.wav")
    END FUNCTION
    
    CALLBACK FUNCTION CBStop
    CALL PlayWave("")
    END FUNCTION
    
    CALLBACK FUNCTION CBMem
    sndPlaySound BYVAL lpbi,%SND_MEMORY OR %SND_ASYNC
    END FUNCTION
    
    FUNCTION PBMAIN() AS LONG
    LOCAL hDlg AS LONG
    LOCAL Fname AS STRING
    Fname="1c-1.wav"
    hMem=LoadResource(BYCOPY %Null,FindResource(BYCOPY %Null,BYCOPY Fname,"RT_RCDATA"))
    lpbi=LockResource(hMem)
    DIALOG NEW 0,"Play Wav",,,320,240,_
     %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
     %WS_MINIMIZEBOX OR %DS_CONTEXTHELP,0 TO hDlg
    IF hDlg=0 THEN EXIT FUNCTION  ' Error occurred
    CONTROL ADD BUTTON,hDlg,200,"Play "+Fname,130,60,60,20,0 CALL CBPlay()
    CONTROL ADD BUTTON,hDlg,201,"Play Memory Copy",130,100,100,20,0 CALL CBMem()
    CONTROL ADD BUTTON,hDlg,202,"Stop Playing",130,140,60,20,0 CALL CBStop()
    DIALOG SHOW MODAL hDlg
    FreeResource hMem
    END FUNCTION

    ------------------

    Comment


    • #3
      Joe --
      Begin from: PlaySound "C:\Reminder.wav", ByVal 0, %SND_FILENAME

      Bellow you can find the description of PlaySound from another variant win32.hlp.

      The PlaySound function plays a sound specified by the given filename, resource, or system event. (A system event may be associated with a sound in the registry or in the WIN.INI file.)

      BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound );
      Parameters

      pszSound

      A string that specifies the sound to play. If this parameter is NULL, any currently playing waveform sound is stopped. To stop a non-waveform sound, specify SND_PURGE in the fdwSound parameter.
      Three flags in fdwSound (SND_ALIAS, SND_FILENAME, and SND_RESOURCE) determine whether the name is interpreted as an alias for a system event, a filename, or a resource identifier. If none of these flags are specified, PlaySound searches the registry or the WIN.INI file for an association with the specified sound name. If an association is found, the sound event is played. If no association is found in the registry, the name is interpreted as a filename.

      hmod

      Handle of the executable file that contains the resource to be loaded. This parameter must be NULL unless SND_RESOURCE is specified in fdwSound.

      fdwSound

      Flags for playing the sound. The following values are defined:

      SND_APPLICATION

      The sound is played using an application-specific association.

      SND_ALIAS

      The pszSound parameter is a system-event alias in the registry or the WIN.INI file. Do not use with either SND_FILENAME or SND_RESOURCE.

      SND_ALIAS_ID

      The pszSound parameter is a predefined sound identifier.

      SND_ASYNC

      The sound is played asynchronously and PlaySound returns immediately after beginning the sound. To terminate an asynchronously played waveform sound, call PlaySound with pszSound set to NULL.

      SND_FILENAME

      The pszSound parameter is a filename.

      SND_LOOP

      The sound plays repeatedly until PlaySound is called again with the pszSound parameter set to NULL. You must also specify the SND_ASYNC flag to indicate an asynchronous sound event.

      SND_MEMORY

      A sound event’s file is loaded in RAM. The parameter specified by pszSound must point to an image of a sound in memory.

      SND_NODEFAULT

      No default sound event is used. If the sound cannot be found, PlaySound returns silently without playing the default sound.

      SND_NOSTOP

      The specified sound event will yield to another sound event that is already playing. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound.
      If this flag is not specified, PlaySound attempts to stop the currently playing sound so that the device can be used to play the new sound.

      SND_NOWAIT

      If the driver is busy, return immediately without playing the sound.

      SND_PURGE

      Sounds are to be stopped for the calling task. If pszSound is not NULL, all instances of the specified sound are stopped. If pszSound is NULL, all sounds that are playing on behalf of the calling task are stopped.
      You must also specify the instance handle to stop SND_RESOURCE events.

      SND_RESOURCE

      The pszSound parameter is a resource identifier; hmod must identify the instance that contains the resource.

      SND_SYNC

      Synchronous playback of a sound event. PlaySound returns after the sound event completes.

      Return Values

      Returns TRUE if successful or FALSE otherwise.

      Remarks

      The sound specified by pszSound must fit into available physical memory and be playable by an installed waveform-audio device driver. PlaySound searches the following directories for sound files: the current directory; the Windows directory; the Windows system directory; directories listed in the PATH environment variable; and the list of directories mapped in a network. For more information about the directory search order, see the documentation for the OpenFile function.

      If it cannot find the specified sound, PlaySound uses the default system event sound entry instead. If the function can find neither the system default entry nor the default sound, it makes no sound and returns FALSE.


      ------------------

      Comment


      • #4
        Thanks Semem, that helped. With a little experimenting I found
        that BYVAL STRPTR(MString) was the correct syntax for the first
        parameter. Trial and error for this was complicated by the fact
        that I opened the file as RANDOM, not BINARY so the string I was
        loading was the NULL string.

        For anyone interested, the working program is below. You can
        now play a WAV file from HDD, or from a copy loaded into a
        string. Next I plan to "compute" the WAV file as a Sine wave
        tone. (Already have that working in PBCC).

        I am puzzled by matching parameters to expected types. PLAYSOUND
        obviously accepts string constants for the first parameter,
        e.g. "1c-1.wav" below. However substituting Fname, which is
        a string with the same value, causes a syntax error. Why is
        that, I wonder? Using BYVAL STRPTR(MString) gets by the
        syntax error and works if %SND_MEMORY is present. But the
        syntax BYVAL STRPTR(Fname) is not equivalent when %SND_MEMORY
        is NOT PRESENT. (I suspect if it were Wednesday it would work).

        The "working program" is quite straightforward, once you know
        the proper syntax for the function calls!
        ----------------------------------------------------------------
        Code:
        #COMPILE EXE
        #REGISTER NONE
        $INCLUDE "WIN32API.INC"
        GLOBAL MString AS STRING
        GLOBAL Fname AS STRING
        
        CALLBACK FUNCTION CBPlay:PlaySound "1c-1.wav",0,%SND_ASYNC:END FUNCTION
        CALLBACK FUNCTION CBMemo:PlaySound BYVAL STRPTR(MString),0,%SND_MEMORY OR %SND_ASYNC:END FUNCTION
        CALLBACK FUNCTION CBStop:PlaySound "",0,%SND_ASYNC:END FUNCTION
        
        FUNCTION PBMAIN() AS LONG
        LOCAL hDlg AS LONG
        LOCAL Fname AS STRING
        Fname="1c-1.wav"
        OPEN Fname FOR BINARY AS #1:GET$ 1,LOF(1),MString:CLOSE #1
        DIALOG NEW 0,"Play Wav",,,320,240,_
         %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
         %WS_MINIMIZEBOX OR %DS_CONTEXTHELP,0 TO hDlg
        IF hDlg=0 THEN EXIT FUNCTION  ' Error occurred
        CONTROL ADD BUTTON,hDlg,200,"Play "+Fname,110,60,100,20,0 CALL CBPlay()
        CONTROL ADD BUTTON,hDlg,201,"Play Memory Copy",110,100,100,20,0 CALL CBMemo()
        CONTROL ADD BUTTON,hDlg,202,"Stop Playing",110,140,100,20,0 CALL CBStop()
        DIALOG SHOW MODAL hDlg
        END FUNCTION
        ------------------

        Comment


        • #5
          The equates have nothing to do with your problem of passing dynamic strings to the PlaySound() API.

          PlaySound expects it's 1st parameter as a pointer to a zero-terminated string - that is, a pointer to an ASCIIZ string.

          To pass a dynamic string, you could pass the string BYCOPY, or convert the parameter into an expression (which is passed BYCOPY):
          ie,
          fName$ + ""
          or
          BYCOPY fName$
          or
          (fName$)


          ------------------
          Lance
          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          Lance
          mailto:[email protected]

          Comment


          • #6
            Lance, I thought I had tried BYCOPY so I went back and tried it
            again. While it compiles and executes without error, it
            does not execute correctly. I get no sound at all.

            It appears that,

            [copy]
            Fname="xxxx.WAV"
            PlaySound BYCOPY Fname,0,%SND_ASYNC

            and,

            PlaySound "xxxx.WAV",0,%SND_ASYNC
            [/copy]

            are not equivalent.

            The other forms Fname+"" and (Fname) produce the same result.
            -----------------------------------------------------------------




            ------------------

            Comment


            • #7
              Originally posted by Joe Speroni:
              It appears that,
              Fname="xxxx.WAV"
              PlaySound BYCOPY Fname,0,%SND_ASYNC

              and,

              PlaySound "xxxx.WAV",0,%SND_ASYNC
              are not equivalent.

              The other forms Fname+"" and (Fname) produce the same result.
              Not equal ?! Test this
              Code:
              #Compile Exe
              #Dim All
              #Register None
              #Include "WIN32API.INC"
              Function PbMain
                PlaySound "C:\Reminder.wav", ByVal 0, %SND_FILENAME 'Or %SND_ASYNC
                Sleep 5000
                Dim FName As String
                FName = "C:\Reminder.Wav"
                PlaySound ByCopy Fname, 0,%SND_ASYNC
                Sleep 5000
                PlaySound ByVal StrPtr(Fname), 0,%SND_ASYNC
                Sleep 5000
                PlaySound "C:\Reminder.wav",0,%SND_ASYNC
              End Function

              ------------------

              Comment


              • #8
                Ooops, I had

                GLOBAL Fname AS STRING

                and

                LOCAL Fname AS STRING

                in the same program. (see above). The CALLBACK FUNCTION was
                "seeing" the GLOBAL copy that was a NULL string. So it didn't
                appear to work. Thanks for proving me wrong. In the future
                I'll be able to use these constructs a little more freely,
                now that my mind believes they work.
                ----------------------------------------------------------------
                Code:
                #COMPILE EXE
                #REGISTER NONE
                $INCLUDE "WIN32API.INC"
                GLOBAL Fname AS STRING
                
                CALLBACK FUNCTION CBPlay0:PlaySound "C:\Reminder.wav",0,%SND_ASYNC:END FUNCTION
                CALLBACK FUNCTION CBPlay1:PlaySound (Fname),0,%SND_ASYNC:END FUNCTION
                CALLBACK FUNCTION CBPlay2:PlaySound BYCOPY Fname,0,%SND_ASYNC:END FUNCTION
                CALLBACK FUNCTION CBPlay3:PlaySound BYVAL STRPTR(Fname),0,%SND_ASYNC:END FUNCTION
                
                FUNCTION PBMAIN() AS LONG
                LOCAL hDlg AS LONG
                Fname="C:\Reminder.wav"
                DIALOG NEW 0,"Play Wav",,,320,240,_
                 %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MAXIMIZEBOX OR _
                 %WS_MINIMIZEBOX OR %DS_CONTEXTHELP,0 TO hDlg
                IF hDlg=0 THEN EXIT FUNCTION  ' Error occurred
                CONTROL ADD BUTTON,hDlg,200,"Play "+CHR$(34)+"C:\Reminder.wav"+CHR$(34),110,60,100,20,0 CALL CBPlay0()
                CONTROL ADD BUTTON,hDlg,201,"Play ("+Fname+")",110,100,100,20,0 CALL CBPlay1()
                CONTROL ADD BUTTON,hDlg,202,"Play BYCOPY Fname",110,140,100,20,0 CALL CBPlay2()
                CONTROL ADD BUTTON,hDlg,203,"Play ByVal StrPtr(Fname)",110,180,100,20,0 CALL CBPlay3()
                DIALOG SHOW MODAL hDlg
                END FUNCTION

                ------------------

                Comment

                Working...
                X