home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-23 | 85.8 KB | 2,059 lines |
- This document is pure ASCII text format; it may be viewed in any text editor,
- or by the "type" command at a DOS prompt. It's not really optimized for
- printout; if you want a hardcopy, we really recommend printing from WINSTK.DOC
- (which is in Microsoft Word format). It will give you nice pagination,
- courier monospace and other fonts, a table of contents, an index, etc.
-
- DiamondWare's Sound ToolKit for Windows (The WIN-STK) was brought to
- you by DiamondWare, Ltd.
-
- You can contact us via:
- internet email: support@dw.com
- Web Page: www.dw.com
- CompuServe: 73704,245
- voice: (602) 917-3474
- FAX: (602) 917-5973
- snail-mail: 2095 N. Alma School Rd., Suite 12-288, Chandler, AZ 85224
-
- The WIN-STK software was designed and developed by John C. Lundy, Erik
- Lorenzen, and Keith Weiner.
-
- Example source code was developed by John Lundy, with language-specific
- help from Dave Allen (Visual BASIC), and David Bollinger (Delphi).
-
- This document was written and edited by Keith Weiner. Proofreading was done
- by Joyce Weiner, Angelo Nunes, Erik Lorenzen, John Lundy, Dave Allen and
- David Bollinger.
-
- The Visual BASIC interface was written by Dave Allen. The Delphi interface
- was written by David Bollinger.
-
- This software and documentation are Copyright 1994-1996 DiamondWare,
- Ltd. All rights reserved. DiamondWare's Sound ToolKit, DiamondWare's
- STK, The STK, The WIN-STK, DiamondWare, DW, and DW are trademarks of
- DiamondWare, Ltd.
-
- The included sample MIDI song is Copyright 1994 David Schultz, All Rights
- Reserved. Used by permission. May not be used without written permission
- from David Schultz.
-
- DiamondWare also offers a full range of consulting and software development
- services, from device-driver development to turnkey multimedia titles. Please
- call us for more information.
-
- Borland is a registered trademark, and Delphi is a trademark of Borland
- International Inc.
- Visual Age is a trademark, and IBM is a registered trademark of IBM Corp.
- Microsoft and Win32 are registered trademarks of, and Windows and Visual
- BASIC are trademarks of Microsoft Corporation
- Symantec is a trademark of Symantec Corporation
- Watcom is a trademark of Watcom Systems, Inc.
-
- License Agreement: Commercial Version
- This document is a legal agreement between you and DiamondWare, Ltd. By using this software,
- you agree to be bound by the terms of this Agreement and Disclaimer of Warranty and Limited
- Warranty. If you do not agree to the terms of this Agreement, promptly return the software and all
- accompanying items for a full refund.
- 1. GRANT OF LICENSE. This License Agreement permits you (one person) to use one copy of the
- enclosed Sound ToolKit for Windows software and documentation (The WIN-STK) on a single
- computer.
- 2. COPYRIGHT. The WIN-STK is owned by DiamondWare, Ltd., and is protected by United
- States copyright law and international treaty provisions. You must treat the WIN-STK like any
- other copyrighted work except that you may either (a) make one copy solely for backup or archival
- purposes, or (b) transfer the WIN-STK to your hard disk, provided that you keep the original solely
- for backup or archival purposes. You may not copy the written materials accompanying the WIN-
- STK. You may be held legally liable for any copyright infringement that is caused or encouraged
- by your failure to abide by the terms of this Agreement.
- 3. OTHER RESTRICTIONS. You may not rent or lease the WIN-STK. It is licensed to you, the
- Licensee. The license may not be transferred to any other party without the prior written consent of
- DiamondWare, Ltd. You may not reverse engineer, decompile, or disassemble the WIN-STK.
- 4. DISTRIBUTION. You are hereby granted a royalty-free non-exclusive right to reproduce and
- distribute the WIN-STK DLLs as part of your software, provided that it does not compete with, or
- substantially duplicate the functionality of, the WIN-STK. You must credit the WIN-STK wherever
- your other credits appear.
-
- License Agreement: Demo Version
- This version of the WIN-STK is SHAREWARE. DiamondWare grants you a personal license to
- evaluate the WIN-STK for 30 days. This license is for evaluation purposes only. You may not
- distribute this SHAREWARE version of the WIN-STK as part of any other software. In any event,
- after 30 days, you must pay the license fee or stop using the STK.
-
- DiamondWare also grants permission to distribute this SHAREWARE version of the WIN-STK
- under the following terms:
- 1. You must include all of the files listed in PACKING.LST.
- 2. You must make it clear that the WIN-STK is SHAREWARE.
-
- Disclaimer of Warranty and Limited Warranty
- The WIN-STK diskette and accompanying written materials are sold "as is", without warranty or
- guarantee as to their performance, merchantability, or fitness for any particular purpose. The entire
- risk as to the results and performance of the WIN-STK is assumed by you.
- However, the magnetic diskette on which the software is recorded is warranted to be free from
- defects in materials and workmanship under normal use for a period of ninety days from the date of
- purchase. If, during this ninety-day period, the diskette should prove defective, it may be returned
- for a replacement without charge, provided you have registered your WIN-STK license via mail.
- Your sole and exclusive remedy in the event of a defect is expressly limited to replacement of the
- diskette, as provided above.
- Any implied warranties relating to the diskette, including any implied warranties of
- merchantability and fitness for a particular purpose, are limited to a period of ninety days from the
- date of purchase. Neither DiamondWare, nor its partners, agents, distributors, or contractors, shall
- be liable for indirect, special, or consequential damages resulting from the use of this product.
-
- Free Upgrade Policy for Bug Finders
- DiamondWare is committed to the goal of zero-defect software.
-
- Bug-free programs do not happen by accident. They are the result of a thorough
- design, a scientific approach to coding, and extensive testing of the finished
- product. By the time we ship a product, we have more than just a hope that our
- products are robust. We have an expectation, based on evidence.
-
- You shouldn't find any bugs in our code.
-
- But if you do, your foremost concern (and ours) is getting the problem fixed
- properly, verifying the fix, and getting you an update.
-
- For your trouble, we're prepared to offer you a free upgrade to the next major
- version. This isn't really adequate payment for your time or aggravation. But
- it's our way of showing some appreciation for what is otherwise a grueling and
- thankless task.
- Conditions
- The defect must be non-trivial.
- You must be the first to report it.
- Upon our request, you must provide us with a test program which
- demonstrates the bug.
- The bug must be caused by DiamondWare's code.
- Cosmetic problems are excluded from this policy, although we'll try to
- provide fixes quickly.
- Operating system or driver bugs are also excluded, although we'll try to
- provide workarounds.
- The final decision, whether or not to award a free upgrade, lies with
- DiamondWare.
-
- Please help us make the product better by reporting any problem you encounter
- with DiamondWare software.
-
-
- Upgrade Policy
- It's our policy to make minor version upgrades available to registered users of
- our products free of charge.
-
- Minor version upgrades include bug fixes, performance improvements,
- additional new features, etc.
-
- Normally, minor version upgrades are distributed electronically.
-
- Major version upgrades will constitute at least one non-trivial new feature, and
- several other features. A major version means that substantial new code was
- developed; possibly the product was rewritten from the ground up.
-
- New major versions are offered to existing customers at a substantial discount;
- in the past, the discount has been 50%.
-
-
- Introduction
- This manual is organized into three major sections. The first is the Guide.
- Although you can skip the some of its topics, it contains some invaluable
- information about the WIN-STK, including useful hints and troubleshooting
- help.
-
- The second section is the Tutorial. It will take you step by step through some
- code which uses the STK. If you're familiar with the DOS-STK, or prefer to
- read the files on disk, you might skip this section; it is not essential.
-
- The third section is the Reference. You might want to skim it before writing
- your code; it's always a good idea to achieve closure with any API you use.
-
- Guide to the WIN-STK
- This section gives an overview of the product, but also contains some specific
- information, and recommendations.
- What Is It?
- DiamondWare's Sound ToolKit for Windows (The WIN-STK) is a sound library
- which provides functions to support interactive sound and music.
-
- What does this mean? Windows can play MIDI and WAVE files already.
-
- That's true. However, Windows cannot play more than one sound at a time, nor
- even reliably tell you when it's done playing. The rest of this Guide will discuss
- the feature set of the WIN-STK, and explain how to use it.
-
- The WIN-STK is supplied as four DLLs: one for 16- and one for 32-bit Windows
- (and two more for Win32s), so it can be used from almost any programming or
- authoring environment. We provide all the files you'll need if you're using
- C/C++ from Microsoft, Borland, Watcom, Symantec, or IBM; or if you're using
- Visual BASIC, or Delphi.
-
- The WIN-STK implements a superset of our acclaimed API, originally
- introduced for the DOS version. Its architecture will impact yours minimally (if
- at all), so adding the WIN-STK to a mostly-completed program will be easy.
-
- The WIN-STK provides an object-oriented sound-centered API, which is
- cleaner and easier to use than a channel-centered system. With the WIN-STK,
- you don't have to allocate or deallocate channels.
-
- The WIN-STK supports (and has been tested under!) Windows 3.1, Windows
- 95, and Windows NT.
-
- The WIN-STK requires a minimum platform of a 486. We recommend a 486-
- 66, however.
- What Does It Do?
- It plays up to sixteen digital sounds (WAVEs) at the same time, plus one MIDI
- song. Your program selects the digitized mode (mono or stereo, bits/sample,
- and sampling rate) and which MIDI device to use.
-
- The salient features of the WIN-STK are listed below.
-
- Random Access. You can start or stop any sound at any time.
-
- Low latency. Latency is the time elapsed between your call to play a sound,
- and when the sound is actually heard. Typically, for Windows 95 and NT, the
- WIN-STK latency figures are: 100 milliseconds average, 75ms best case, and
- 125ms worst case. For Windows 3.1, they are 200ms average, 150 best, and
- 250 worst. This is good enough to convince users that a sight and sound
- occurred simultaneously. (Though it's probably not good enough for a
- keyboard synthesizer application.)
-
- DSP. You can alter the pitch and volume of each sound.
-
- Stereo. The WIN-STK can play a monophonic (or stereo sound) through both
- stereo output channels, with a different volume in each (panning).
-
- Interactivity. Even after a sound is playing, you can change its pitch and
- volume, loop count, etc. The WIN-STK can notify you when a sound is done
- playing, giving you the opportunity to display graphics or execute a handler.
-
- Sequencing. The WIN-STK allows you to play a sound right after another,
- guaranteeing that the sequenced sound will play exactly when the first is done,
- without an overlap, click, or pause.
-
- Music. The WIN-STK can play a MIDI song.
- Where Is It Going in the Future?
- This version of the WIN-STK was released because it provides a valuable
- feature set to many programmers, who are trying to mix several channels of
- digital audio.
-
- But it's not the penultimate system. Here's sneak preview of future WIN-STKs.
-
- Better MIDI support. This includes volume control, callbacks for SysEx and
- other events, multiple songs playing at the same time, segueing, branching, etc.
- In other words, interactive music.
-
- DirectSound and Native Audio support.
-
- Recording. A future version will support recording, as well as playback. Added
- bonus: some boards support simultaneous record/playback, which is perfect for
- networked games!
-
- Other features, To Be Determined: If there's something you really want to see,
- please let us know!
-
- Development Environments
- Before proceeding any further, you should be familiar with such programming
- topics as bitfields and using DLLs.
-
- The WIN-STK will work with any development environment which can load
- and call DLLs, however this document discusses C/C++, Visual BASIC, and
- Pascal specifically.
- Language Notes for C/C++
- The WIN-STK has been tested with compilers from Microsoft, Borland,
- Watcom, Symantec, and IBM. DWS.H passes through all of them without any
- warnings. The sample program PLAYSTK also works with all. However, we
- provide a 16- and 32-bit .LIB file for each compiler.
-
- In some compilers, you may need to add the common dialog library into your
- project in order to build PLAYSTK.EXE. See your compiler's manual for
- details.
-
- This manual was written using C terminology, so if you're familiar with ANSI
- C, and a modern commercial Windows compiler, you should be able to read this
- manual with 100% comprehension.
-
- As with other libraries, the WIN-STK provides an include file. Put the line:
-
- #include "dws.h"
-
- at the top of every source module which uses the WIN-STK.
-
- If you've never written a program using a DLL before, there are two ways to do
- it. We'll call the first "The Easy Way", and the second "The Hard Way."
-
- In The Easy Way, you link with an import library. This usually comes with the
- DLL, or most compilers provide a utility called IMPLIB.EXE which can make
- one. The import library provides a stub for each function in the DLL. It takes
- care of the magic of loading the DLL, determining runtime addresses, etc.
-
- The WIN-STK comes with an import library for the most popular compilers; if
- we didn't provide one for your compiler, look for IMPLIB.EXE in your
- compiler's BIN directory.
-
- In The Hard Way, you do everything yourself. You manually load the DLL,
- calculate the address of every function you need within it, and call those
- functions through pointers. The Hard Way is beyond the scope of this
- documentation, but it's mentioned for completeness.
-
- Some programmers use the standard-library function atexit to register
- cleanup functions, which are called before the program terminates. You must
- not use this facility to call dws_Kill. This is because Windows 95 and NT
- will wait until all threads except the main thread stop executing. The WIN-STK
- uses a background thread which is terminated during the call to dws_Kill.
- This will lead to an impasse, where the program will not quite terminate.
-
- The atexit problem does not apply to 16-bit programs, but if you think that
- you will ever move to Win32, you should probably avoid it anyway.
- Language Notes for Visual BASIC
- The WIN-STK supports Visual BASIC 3 and Visual BASIC 4, including the
- new 32-bit mode.
-
- In the reference section, you will find a prototype for each WIN-STK function
- in C, Visual BASIC, and Pascal. However, this document is somewhat C-
- centric.
-
- Read on for some information which will help you comprehend the rest of the
- manual.
-
- In C, all procedures are called "functions", although in Visual BASIC they may
- be "functions" or "subroutines", depending on whether they return a value.
-
- In C, variables are declared type first, and then variable name:
-
- int x;
-
- This declares a variable called x, of type integer. Pointers are declared with a
- star, like:
-
- int *y;
-
- Here, y is a pointer to integer. Some WIN-STK functions take pointer
- parameters, and the sample C code in this document will use this notation.
-
- A C struct, often called a structure, is the equivalent of a Visual BASIC user-
- defined Type.
-
- C comments are either a double slash //Comment which is a comment until
- the end of the line, equivalent to Visual BASIC's apostrophe ' or REM; or
- /*Comment*/, which is a comment between the /* and the */.
-
- C expresses bitwise OR as a pipe |, bitwise AND as an ampersand &, boolean
- OR as two pipes ||, and boolean AND as two ampersands &&.
-
- In C, the ampersand & operator can also be used to take the address of a
- variable. For example:
-
- dws_MSongStatus(&mstat);
-
- This call passes the address of the variable mstat to dws_MSongStatus.
- By default, Visual BASIC passes parameters by reference, so you probably
- won't have to deal with this issue.
-
- In C, the default is to pass a parameter by value, which in VB requires the use of
- the ByVal keyword.
-
- To pass a NULL pointer in Visual BASIC, you need to specify a 32-bit 0:
-
- dws_DGetInfo(dplay, ByVal 0&);
-
- We provide DWS.BAS, which declares all of the constants, data types, and
- routines of the WIN-STK. Add this file to your project. You might also want to
- read through it.
-
- The WIN-STK can send your window a message when a digitized sound is done
- playing. But Visual BASIC alone does not allow you to receive or process
- specific window messages. You will need a third-party VBX or OCX control to
- use this feature.
- Language notes for Pascal
- The WIN-STK works with the various Windows Pascal products published by
- Borland. However, the sample program PLAYSTK, will only compile with
- Delphi.
-
- In the reference section, you will find a prototype for each WIN-STK function
- in C, Visual BASIC, and Pascal. However, this document is somewhat C-
- centric.
-
- Read on for some information which will help you comprehend the rest of the
- manual.
-
- In C, all code routines are called "functions", although in Pascal they may be
- "functions" or "procedures", depending on whether they return a value.
-
- In C, variables are declared type first, and then variable name:
-
- int x;
-
- This declares a variable called x, of type integer. Pointers are declared with a
- star, like:
-
- int *y;
-
- Here, y is a pointer to integer. Some WIN-STK functions take pointer
- parameters, and the sample C code in this document will use this notation.
-
- A C struct, often called a structure, is the equivalent of a Pascal record.
-
- C comments are either a double slash //Comment which is a comment until
- the end of the line or /*Comment*/, which is equivalent to Pascal's
- (*Comment*).
-
- C expresses bitwise OR as a pipe |, bitwise AND as an ampersand &, boolean
- OR as two pipes ||, and boolean AND as two ampersands &&.
-
- In C, the ampersand & operator can also be used to take the address of a
- variable. For example:
-
- dws_MSongStatus(&mstat);
-
- This call passes the address of the variable mstat to the function (which puts
- the song's status into the variable). This is equivalent to Pascal's var calling
- convention.
-
- We provide DWS.PAS, which declares all of the constants, data types, and
- routines of the WIN-STK. You will need to insert the line:
-
- uses dws;
-
- into your main program. You might also want to read the source.
-
- Pascal is not case-sensitive. This will cause the dws_DPLAY and dws_MPLAY
- record types to conflict with the corresponding function names. Therefore, they
- have a REC at the end (e.g. dws_DPLAYREC and dws_MPLAYREC).
-
- In Pascal, the identifier message is a keyword. Therefore in Pascal, the
- message field in the dws_DPLAY record is renamed wmessage.
-
- Another problem with Pascal and the WIN-STK is that the functions
- dws_DGetInfo and dws_DSetInfo take two dws_DPLAYREC parameters
- which are passed by reference (declared as var). To tell these functions to
- ignore a parameter, C and Visual BASIC programmers can pass a NIL. The
- Pascal compiler will not let you do this directly. But there is another way of
- indicating "ignore this parameter". The dws_DPLAYREC record has a flags
- field which indicates which other fields within the record you are using. If you
- set flags = 0, then the WIN-STK will behave exactly as if you had passed
- NIL as the address of the record. See the Reference section for more details.
-
- The dws_WAV2DWD function also accepts a NIL pointer in certain cases.
- However, the parameter is not a pass-by-reference variable in this function. It's
- a PBYTE, so the compiler will let you pass NIL.
-
- This document will not further refer to these differences between Pascal and C.
- Installing the WIN-STK
- Simply copy (or unzip) the WIN-STK files into their own subdirectory tree on
- your hard drive. There are different subdirectories for C, Visual BASIC, Pascal,
- the DLLs, etc. You probably don't need all of them.
-
- Make sure you put the files for your language where your compiler and linker
- can find them. If you need more information on this and related topics, your
- compiler's manual will be far more detailed than is possible here, and will cover
- your specific software environment.
- Installing a WIN-STK-using Program
- When you install your program on the user's machine, please put the WIN-STK
- DLLs in the same directory as your executable(s). This will ensure that other
- programs using different versions of the WIN-STK will coexist with yours. In
- fact, this is a good practice for all DLLs in Windows.
- Using the WIN-STK Effectively
- The Tutorial and Reference sections describe, in great detail, how to use the
- WIN-STK. Here, we discuss some of the issues to think about if you want to
- use the WIN-STK effectively.
- Stereo or Mono?
- The WIN-STK can output stereo or mono sound. In most cases, you will want
- to use stereo if supported by the hardware. Elsewhere in this manual, you'll
- find out how to determine if stereo is available. You might want to use mono,
- however, to save precious CPU cycles on slower machines. Elsewhere, we
- discuss other things to do to maximize performance.
-
- So you've decided to use stereo. But have you thought about your source
- sounds? Should you record them in stereo?
-
- The answer depends on what you are trying to do. If you are playing any kind
- of cinematic sequence, then stereo recording is probably appropriate.
-
- But if you want your sound to be interactive, then mono is probably a better
- choice because the WIN-STK can play the left and right channels at different
- volume levels. This is called panning, and can be used to communicate a
- sound's location to the user. In fact, many 3D games use panning to localize
- sound.
- Authoring Sound
- If you're authoring a long playback sequence, with little or no interactivity to it,
- you may author literally anything which the hardware can play back. The
- sampling rate, sample size, and whether to use stereo will be dictated by your
- creative designer, and storage considerations.
-
- But if you're producing sound to be played simultaneously with other sounds
- and be manipulated by the program, read on.
-
- The first issue to consider is dynamic range. In digital sound playback, there is
- always a limit to how loud a sample can be. All overflows must be clipped. If
- an occasional sample is clipped, then the user will most likely never notice it.
- However, if you overload the system with many loud sounds, then the output
- will sound distorted, which is usually undesirable.
-
- Record your sounds so that they do not use a lot of dynamic range. The goal is
- to minimize the difference between the loud parts and the soft parts, making the
- entire sound somewhat quiet. Good sound editing programs offer a dynamic
- range compression feature for just this purpose.
-
- Keep the overall volume level of your sounds commensurate with how many
- you expect to play at the same time. For example, if you need to play four
- sounds at a time, then each sound should use roughly ¼ of the total dynamic
- range.
-
- If you're going to use volume panning to localize sounds, then you will likely
- want distant sounds to be quiet and close sounds to be loud. In this case, record
- your sound at the loudest level you'll need, and use the WIN-STK to make it
- softer as it moves into the distance.
-
- This will give you better sound quality (as well as being computationally
- faster-see the next topic for details) than recording soft and raising the volume
- at runtime.
- WIN-STK Performance
- 8-bit audio is less CPU intensive than 16-bit. Using 8-bit also allows the WIN-
- STK to perform certain additional optimizations.
-
- So what's the order of fastest to slowest modes? 8-bit mono is fastest, followed
- by 16-bit mono, then 8-bit stereo, then 16-bit stereo. The difference between
- 16-bit mono and 8-bit stereo is slight.
-
- There is a tradeoff between latency (the time between when your program calls
- a sound function, and the time when the user hears it) and CPU usage. A
- smaller internal buffer will allow the WIN-STK to give you lower latency, but it
- will need to be updated more often, thus increasing the CPU load.
-
- Sound, unlike video, can't acceptably stall even briefly. If the buffer is not
- updated by the deadline, an audible gap or click will result. Slower computers,
- of course, will take more time before they can get around to updating the buffer.
- Thus, the WIN-STK will use larger buffers on slower machines, and can get
- away with smaller buffers on faster machines.
-
- The WIN-STK can play up to 16 digital sounds at the same time. But you
- should configure the WIN-STK to allow only for the maximum number of
- voices your program will actually use. Setting this value needlessly high will
- impose CPU usage and latency penalties.
-
- It's important to understand that the WIN-STK will convert sounds (if
- necessary) to the match the output mode. Thus, even if the output mode is 8-bit
- mono, you can still play a 16-bit stereo file.
-
- Obviously, you should author your sounds with the same sample size and
- number of channels as your intended output mode. You should only rely on the
- WIN-STK's automatic format conversions if a user's sound hardware is less
- capable than your target platform. But in any event, the WIN-STK can exploit
- the 8-bit optimizations if either the source sound, or the output mode, is 8-bit.
-
- Volume change is always faster than pitch change. Lowering the pitch is always
- faster than raising it.
-
- With 8-bit sound, lowering the volume is faster than raising the volume. With
- 16-bit sound, there is no difference in CPU usage.
- 16-bit vs. 32-bit DLLs
- The 16-bit DLL works under Windows 3.1, Windows 95, and Windows NT.
- The 32-bit DLL works only under Windows 95, and NT because it makes
- extensive use of multithreading.
- 16-Bit
- The 16-bit DLL is susceptible to all of the problems you normally have in
- Windows 3.1. If your application hogs the CPU for a while, then the WIN-STK
- might stop playing sound until you yield again. To get around this problem, we
- provide a function (dws_Update) that you can call to keep the sound going,
- even if you don't want to yield to the system.
-
- If another application hogs the CPU (or if your user drags your window around
- by the title bar), then the sound will pause. There isn't anything that anyone can
- do about it.
- 32-Bit
- The 32-bit DLL is immune to the above problems; Win32 is a superior platform
- to Win16!
-
- Be aware, however, that if you really hog the CPU within a very high-priority
- thread, you can cause the sound to pause. You probably shouldn't be doing this,
- but if you must, then you must call dws_Update periodically. High-priority
- threads should only be used for fast, critical actions.
-
- The 32-bit DLL is fully thread-safe.
-
- The WIN-STK kernel thread runs at THREAD_PRIORITY_TIME_CRITICAL
- priority. This results in a base priority level of 15 for calling processes with a
- priority class of IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or
- HIGH_PRIORITY_CLASS; and a base priority level of 31 for processes with
- REALTIME_PRIORITY_CLASS. You should think long and hard before you
- set your priority class to anything above HIGH_PRIORITY_CLASS!
- Latency vs. Smooth Playback
- There is a tradeoff between minimizing the latency, and playback which never
- skips. Latency is directly proportional to buffer size. But larger buffers offer
- immunity to skipping. The WIN-STK autodetect function can do a pretty good
- job calculating the buffer size on most machines, but it may not be perfect.
-
- You might provide a slider bar for the user to make changes to the calculated
- buffer size.
- Digitized Sound Theory
- This section presents a basic description of digitized sound, and some of the
- theory. You don't really need to read this, but you may find it interesting and
- useful in the future. Digitized sound on computers will certainly be used in the
- future.
-
- Digitized sound is sound that has been sampled, or quantized. Periodically, the
- analog voltage of a sound signal is measured by a special circuit called an
- Analog to Digital Converter (ADC), and then stored.
-
- Digitized sounds are discretely quantized. This means that there is a finite set of
- possible values for each sample. It also means that there are only samples for a
- finite number of instants in time.
-
- Let's take the case of 8-bit samples. Samples range from -128 to +127. Any
- sound softer than +/-1 is lost. Any sound louder than +127/-128 will be clipped,
- which sounds bad. This overflow problem is compounded if you're mixing
- several sounds together, or processing the sound digitally.
-
- Just as the range of samples is not infinite, neither is the domain. Digitized
- sounds are not contiguous in the time domain. They're sampled at T=1 and
- T=2, but not at T=1.5. There's obviously sound at every moment, even during
- those in between the sample points. But we have no record of it; a graph of
- digitized sound data has a characteristic stair-step shape. We'll look at the
- problems this can cause below.
-
- Digital signal theory asserts that every possible waveform can be represented by
- the sum of a finite series of pure sine waves. The highest frequency sine wave
- in this series is no higher than the highest frequency component present in the
- original wave.
-
- The Nyquist theory of digital signal processing states that, in order to capture a
- waveform containing frequencies up to F, you need to sample it at a rate of at
- least 2F.
-
- Any sampling rate, R, lower than 2F will cause the frequencies above R / 2 to be
- aliased as lower frequencies. This sounds like a metallic overtone on top of the
- original sound.
-
- To visualize this better, think of the infamous problem of drawing a diagonal
- line on a low-resolution screen, or of watching a spinning propeller seem to turn
- slowly backwards. The sampling rate (resolution) of the screen is too low to
- display the line. The sampling rate of the human eye is too low to see a 15,000
- RPM propeller.
-
- When we convert digital samples back to analog, the result looks quite square
- (the stair-step shape mentioned above), and not at all like the original. This is
- an immutable consequence of the process.
-
- The steep vertical segments in the wave are high frequencies. Therefore, you
- must send the signal through a low-pass filter to remove the extra garbage.
- Sound boards all contain low-pass filters for this very reason. In practice, a
- cheap set of speakers would probably act as an effective filter for the higher
- sampling rates.
-
- Although the following doesn't really relate to computer audio, it's interesting
- because it's relevant to every CD player.
-
- Analog filters distort the sound. The steeper the cutoff, the worse they sound.
- So instead of trying to build a filter which passes everything below 20,000 Hz
- and cuts everything above 20,001 Hz, CD players use oversampling. You can
- think of oversampling as "interpolation".
-
- If you convert the sample data to the frequency domain, add extra zeroes for all
- the frequencies above your actual sound data, and convert back to the time
- domain, you'll have a smoother interpolation of the original sound. More
- importantly, the harmonic overtones will be at a higher frequency, and thus
- easier to filter.
-
- So the next time you buy a CD player, don't let the ignorant salesman tell you
- that ".THIS player reads the disc eight times so it doesn't make as many
- errors.". You know now that oversampling is just a technique to produce
- smoother output. Even cheap CD players can read a disc without errors, or else
- CD-ROM's would never work!
-
- Tutorial
- This section will take you through the steps required to add sound to a C
- program, starting with the barest minimum, and leading up to some more
- advanced concepts and features. Every line of code should easily convert to an
- equivalent line in Visual BASIC or Pascal.
-
- The code does not check for errors, or do any of the other things required of
- robust, commercial-quality code.
-
- Caveat: This code has not been tested or compiled! It's good for reading
- through, and to illustrate key WIN-STK implementation issues. But, you're
- better off cutting code out of PLAYSTK than attempting to use the code
- presented here.
- The Basics
- The Variables
- void PlaySoundAndSong(void)
- {
- FILE *fp;
- BYTE *sfx;
- WORD mstatus;
- WORD dsize;
- dws_DETECTRESULTS dres;
- dws_IDEAL ideal;
- dws_MPLAY mplay;
- dws_DPLAY dplay;
-
- We're going to load one sound effect from disk into memory (MIDI songs are
- played directly from disk file). sfx, a pointer, holds the address of the sound
- effect buffer. dres, and ideal are structs required for initialization. dplay,
- a struct, holds all information needed to play the sound effect; mplay, another
- struct, holds information for playing the song.
- Loading Songs and Sounds
- /* Allocate memory */
- fp = fopen("sample.dwd", "rb");
- fseek (fp, 0L, SEEK_END);
- sfx = malloc(dsize = ftell(fp));
-
- /* Load the sound file */
- fseek(fp, 0L, SEEK_SET);
- fread(sound, dsize, 1, fp);
- fclose(fp);
-
-
- This code allocates a buffer to store the sound, and then reads the sound file into
- it. SAMPLE.DWD began as SAMPLE.WAV (an 8-bit mono digitized sound,
- sampled at 11kHz), and was converted by WAV2DWD.EXE.
- Initializing the STK
- /* Run the WIN-STK's autodetect routine */
- dws_DetectHardWare(&dres);
-
- /* Init the WIN-STK */
- ideal.mustyp = dws_muscap_MAPPER;
- ideal.digtyp = dws_digcap_11025_08_1;
- ideal.dignvoices = 2;
- ideal.flags = dws_ideal_NONE;
- dws_Init(&dres, &ideal);
-
- The results of the autodetect are returned in the dres struct.
-
- This code fails to check to see whether the WIN-STK even found a MIDI
- mapper, but just assumes that it's there. The MIDI mapper is installed on most
- machines, but you can't make an assumption like that in real code!
-
- We initialized the ideal struct to request the desired STK services. Note how
- we specified 2 voices. This allows the WIN-STK to run at its most efficient.
- Don't tell the WIN-STK to use any more voices than you need.
-
- After the call to dws_Init, the sound hardware and the WIN-STK are set up
- for business.
- Preparing Songs and Sounds
- /* Prepare to play song */
- mplay.track = "sample.mid";
- mplay.count = 1;
-
- /* Prepare to play digitized sound */
- dplay.flags = dws_dplay_SND;
- dplay.snd = sound;
-
- The mplay struct and the dplay struct are set up prior to the calls to play
- them. The flags field in the dplay struct tells the WIN-STK which fields
- have been initialized. Since we didn't use most of the fields in the struct, they'll
- take on reasonable defaults (see the Reference section for specifics).
- Starting Playback
- /* Play song and sound */
- dws_MPlay(&mplay);
- dws_DPlay(&dplay);
-
- A call to dws_MPlay starts the music, and a call to dws_DPlay begins
- playback of the digitized sound effect.
-
- The flags field in the dws_DPLAY struct was designed to allow you to use as
- many or as few of the features available through the dws_DPlay function as
- you want. At a minimum, you must set dws_dplay_SND. This indicates that
- you have specified a pointer to a sound buffer. All other fields (e.g. pitch, loop
- count, etc.) are optional. The flags mechanism also protects your program from
- breaking when you upgrade to new WIN-STK releases. If there are new
- features, your program won't inadvertantly use them.
- Wait 'Til the Fat Lady Stops Singing
- /* Wait loop */
- do
- {
- dplay.flags = dws_dplay_SOUNDNUM;
- dws_DGetInfo(&dplay, NULL);
- dws_MSongStatus(&mstatus);
-
- } while ((dplay.soundnum) ||
- (mstatus & dws_MSONGSTATUSPLAYING));
-
- To query the sound's status, we call dws_DGetInfo, and look at the
- soundnum field that it sends back to us. When the sound is done playing, this
- field is returned as 0.
-
- Note that if you simply want to play a sound, and wait until it's done playing,
- there's an easy way to do this: simply set the dws_dplay_SYNCHRONOUS
- flag field. This will cause the WIN-STK to wait until the sound is done playing
- before it returns to your program. While it's waiting, it yields to the system.
-
- To query the song's status, we call dws_MSongStatus, with the address of a
- bitfield variable. We're interested in the dws_MSONGSTATUSPLAYING field.
- Shutting Down
- /* Free the memory we allocated above */
- free(sound);
-
- /* We must kill the WIN-STK */
- dws_Kill();
- }
-
- Normally, you would call dws_DDiscard before freeing a sound buffer, but
- in this case, we know that the sound is done.
- The Fancy Stuff
- The WIN-STK does a whole lot more than what we've seen so far. In this topic,
- we'll show you how to play more than one sound at the same time (which is
- called "polyphony"), how to sequence a sound after another, how to use the
- WIN-STK's built-in volume and pitch control, how to change sounds once
- they're playing, how to get notification that a sound is done playing, how to
- play large files from disk (32-bit DLL only), and how to handle WIN-STK
- errors.
- Polyphony
- The WIN-STK kernel was designed to be polyphonic from the ground up, so
- you don't need any special tricks. To play two or more sounds at the same time,
- simply call dws_DPlay more than once.
-
- The example code fragment below assumes that the WIN-STK has been
- initialized. sfx1 and sfx2 are digital sounds in memory.
-
- dplay.flags = dws_dplay_SND |
- dws_dplay_PRIORITY;
- dplay.snd = sfx1;
- dplay.priority = dws_NORMALPRIORITY;
- dws_DPlay(&dplay);
-
- dplay.snd = sfx2;
- dplay.priority = dws_NORMALPRIORITY;
- dws_DPlay(&dplay);
-
- The priority field helps the WIN-STK determine which sound to drop if you
- exceed the maximum number of voices (specified in the dws_IDEAL struct in
- the call to dws_Init). The issue is moot for this example, but may be a factor
- in a real-world application.
-
- Note that you can reuse the dplay struct itself; all WIN-STK functions copy
- what they need from your structs before returning.
- Sequencing
- Sequencing allows you to play a sound back-to-back with another. The first
- sample of the sequenced sound plays right after the last sample of the first
- sound. The effect is that of a single sound playing seamlessly, without a pause
- or even a click.
-
- The presnd field of the dws_DPLAY struct is the key to this feature. To
- sequence sound B after sound A, then set the presnd field of sound B's
- dplay struct to the soundnum of sound A (set by the call to dws_DPlay).
-
- In the example below, assume that dplay1 and dplay2 are both structs of
- type dws_DPLAY.
-
- dplay1.flags = dws_dplay_SND;
- dplay1.snd = sfx1;
- dws_DPlay(&dplay1);
-
- dplay2.flags = dws_dplay_SND | dws_dplay_PRESND;
- dplay2.snd = sfx2;
- dplay2.presnd = dplay1.soundnum;
- dws_DPlay(&dplay2);
-
- This example tells the WIN-STK to wait until the first sound is complete, and
- then play the second.
-
- The WIN-STK will set the soundnum field of dplay2 to the same value as its
- presnd; no matter how many sounds you sequence, they will all have the same
- soundnum.
-
- Note: if you have want to play a sequence of more than two sounds, then some
- manual effort is required; the WIN-STK handles only two at a time: the one
- that's playing, and the one sequenced after it. You must wait until the first
- sound is done (and hence the sequenced sound is playing) before sequencing the
- third. Use dws_DGetInfo to determine when a sound is done.
-
- Sequencing is useful if you want to break a long sound into several pieces. Or,
- if you want to play a sound, and then "branch" to one of several sounds,
- depending on some user-interaction after the first part is played (e.g. a gun fires,
- continuing with either a scream or a ricochet, depending on whether the bullet
- hits).
- Pitch and Volume Control
- The WIN-STK allows you to specify the left and right volume for any sound,
- plus its pitch. Actually, the WIN-STK allows you to control the playback length
- of the sound, which affects the perceived pitch. The distinction is important,
- because increases in the length decrease the pitch (make it lower).
-
- dplay.flags = dws_dplay_SND | dws_dplay_LVOL |
- dws_dplay_RVOL | dws_dplay_PITCH;
- dplay.snd = sfx1;
- dplay.lvol = dws_IDENTITY;
- dplay.rvol = dws_IDENTITY / 2;
- dplay.pitch = dws_IDENTITY * 2;
- dws_DPlay(&dplay);
-
- This example will play a sound, with the right channel softer than the left. It
- will play at a lower pitch than it was recorded at.
-
- In a 3D game, volume control of the left and right channels can be used to
- indicate the direction from which the sound is coming.
-
- Pitch can be used to break up the monotony of a sound that's played many
- times. Just vary the pitch slightly each time you play it.
- Interactive Digitized Audio
- Now, let's take a look at what you can do with a sound once it's playing.
-
- You could terminate it.
-
- dws_DDiscard(dplay.soundnum);
-
- You could terminate it, and all other instances of the same sound file:
-
- dws_DDiscardAO(sfx1);
-
- The "AO" stands for "All Occurrences".
-
- To do anything sophisticated with a sound, you'll need dws_DGetInfo and
- dws_DSetInfo.
- Querying a Sound's Status
- dws_DGetInfo can return information about a playing sound, via a
- dws_DPLAY struct. You just set the flags field to indicate the fields for
- which you want information.
-
- The function knows which sound to look up based on its soundnum, so you will
- need to provide that. Remember to set the dws_dplay_SOUNDNUM bit in
- flags.
-
- dplay.flags = dws_dplay_SOUNDNUM;
- dplay.soundnum = sndnum_from_prior_call_to_dplay;
- dws_DGetInfo(&dplay, NULL);
-
- In the above example, we're asking for the soundnum field of the currently
- playing sound. dplay.soundnum will either be unchanged, or hold a 0 if the
- sound is done playing. There was no sequenced sound, so we pass NULL for
- the second dplay parameter.
- Changing a Sound on the Fly
- You can change the loop count, priority, left and right volume, pitch, and
- callback of a currently-playing (or sequenced) sound.
-
- This example illustrates changing the left-channel volume of a sound:
-
- dplay.flags = dws_dplay_SOUNDNUM | dws_dplay_LVOL;
- dplay.soundnum = sndnum_from_prior_call_to_dplay;
- dplay.lvol = dws_IDENTITY / 4;
- dws_DSetInfo(&dplay, NULL);
- Callbacks
- The WIN-STK can give you notification when a sound starts, ends, or aborts.
- This feature relies on Windows' message queue system. If you know your
- window handle, and have a message handler (Window Procedure) installed for
- the window, then this feature will work for you.
-
- The following example illustrates how to play a sound, so that you'll be notified
- when it's done.
-
- dplay.flags = dws_dplay_SND | dws_dplay_CALLBACK;
- dplay.snd = sfx;
- dplay.hwndmsg = hwnd;
- dplay.message = WM_USER + 1;
- dws_DPlay(&dplay);
-
- The sound will play once. The window whose handle is specified by hwnd will
- receive the WM_USER + 1 message (you should, of course, create constants for
- any messages you intend to use).
-
- Your message handler can do anything it wants, including make WIN-STK
- function calls.
-
- Note: Your message handler must use the lParam parameter to determine
- which event occured. There are three possible WIN-STK callback event types:
- dws_event_SOUNDCOMPLETE, dws_event_SOUNDSTARTED, and
- dws_event_SOUNDABORTED.
- Playing Large Sounds Directly from Disk
- If you have a very large sound files (e.g. a 3-minute 16-bit 44kHz music track),
- you might want to play it directly from the disk.
- Win32
- Under Win32 (Windows 95 and NT), you can easily do this. The operating
- system supports memory-mapped files. The following code snippet illustrates
- how to do this:
-
- void PlayDWDFile(char *filename)
- {
- dws_DPLAY dplay;
- HANDLE hfile;
- HGLOBAL hdwd;
- BYTE *dwd;
-
- hfile = CreateFile(filename, GENERIC_READ, 0,
- NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
-
- hdwd = CreateFileMapping(hfile, NULL,
- PAGE_READONLY,
- 0L, 0L, "DWD");
-
- dwd = (BYTE*)MapViewOfFile(hdwd, FILE_MAP_READ,
- 0L, 0L, 0L);
-
- dPlay.flags = dws_dplay_SND;
- dPlay.snd = dwd;
-
- dws_DPlay(&dPlay);
-
- /* Wait until the file is done playing */
-
- UnmapViewOfFile(dwd);
- CloseHandle(hdwd);
- CloseHandle(hfile);
- }
-
- It's important to clean up by unmapping the file, and closing down the handles!
- Win16
- You can play large files from disk under Windows 3.1 also, though it's a little
- bit more involved. You read the file one manageable chunk at a time, slap a
- DWD header on each chunk, and sequence the chunk after the previous chunk.
- Win32s
- The WIN-STK supports Win32s on Windows 3.1x systems. DWSW32S.DLL is
- the primary DLL for Win32s. It provides the entire documented WIN-STK
- API. It then thunks down to DWSW16S.DLL which then makes calls into
- DWSW16.DLL. The primary difference between the 16- and the main 32-bit
- DLL is multithreading. Under Win32s, therefore, the WIN-STK uses the 16-bit
- kernel to actually perform the work.
-
- If you're using C/C++, the code in DWSW32.LIB will automatically determine
- whether it's running under Win32s or a real Win32 environment (Windows 95
- or NT). It will call into the correct DLL. This library file is equivalent to a
- standard import library, though it was written in C. Its other advantage is that it
- will not terminate your program if it can't find the DLL (it will instead report no
- sound capabilities present-true enough without the WIN-STK DLLs).
-
- In Win32s systems, you must install DWSW32S.DLL, DWSW16S.DLL, and
- DWSW16.DLL. But, you will only need to deliver only one executable-at
- least as far as the WIN-STK goes. However, there are many substantial
- differences between different implementations of Win32s, especially so with
- Win32s. Caveat programmer!
-
- Note: Visual BASIC and Pascal/Delphi users do not have access to this C/C++
- mechanism and must provide a separate executable file for Win32s and
- Windows 95/NT.
-
- For 32-bit VB4, if you want to make an executable which runs under Win32s,
- you will need to change DWS.BAS. In each WIN-STK function declaration,
- change "DWSW32.DLL" to "DWSW32S.DLL". This DLL is the correct one
- for Win32s.
-
- For 32-bit Delphi 2, if you want to make an executable which runs under
- Win32s, you will need to change DWS.PAS. Change the line which contains
- DWSDLL = 'DWSW32'; to DWSDLL = 'DWSW32S'; instead. This DLL is the
- correct one for Win32s.
- Error Handling
- The WIN-STK can often tell you when you're making a mistake. All functions
- have a boolean return value. A 1 means success. A 0 means an error of some
- kind occurred. In this case, you should call dws_ErrNo to determine which.
-
- if (dws_DetectHardWare(&dres) == 0)
- {
- err = dws_ErrNo();
-
- DisplayErr("during dws_DetectHardWare");
- }
-
- We provide the source code to DisplayErr in C, BASIC, and Pascal. Just
- look inside PLAYSTK.C, PLAYSTK.BAS, or PLAYSTK.PAS, respectively.
-
- Reference
- This section is broken down into topics for the Functions, the Errors, the Data
- Structures, the Utilities, and the File Formats.
-
- Each is the definitive specification on its subject, with a minimum of verbiage.
- The Functions
- There are 21 functions in the WIN-STK library.
-
- Unless otherwise noted, you must call dws_Init before calling any other
- WIN-STK function.
-
- For each function, we give the prototypes for C, Visual BASIC, and Pascal. We
- give a description, the parameters, related functions, and the complete list of
- errors that the function might generate. You may assume that the list of errors is
- complete; if an error is not listed for a given function, then that function cannot
- flag that error.
-
- dws_DClear
- Declarations
- WORD dws_DClear(void);
- Declare Function dws_DClear() As Integer
- function dws_DClear : WORDBOOL;
- Description
- This function stops all digitized sounds.
- Parameters
- None.
- Related Functions
- dws_DDiscard, dws_DDiscardAO, dws_DPlay
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_DDiscard
- Declarations
- WORD dws_DDiscard(WORD soundnum);
- Declare Function dws_DDiscard(ByVal soundnum As
- Integer) As Integer
- function dws_DDiscard(soundnum: WORD) : WORDBOOL;
- Description
- This function stops the specified sound.
- Parameters
- soundnum number of the sound to be killed
- Related Functions
- dws_DClear, dws_DDiscardAO, dws_DPlay
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_DDiscardAO
- Declarations
- WORD dws_DDiscardAO(BYTE *snd);
- Declare Function dws_DDiscardAO(snd As Long) As
- Integer
- function dws_DDiscardAO(snd: PBYTE) : WORDBOOL;
- Description
- This function stops all occurrences of a DWD. It's useful if you have repeatedly
- played the same sound effect, and want to stop all instances.
- Parameters
- snd ptr to the DWD to stop
- Related Functions
- dws_DClear, dws_DDiscard, dws_DPlay
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_DetectHardWare
- Declarations
- WORD dws_DetectHardWare(dws_DETECTRESULTS *dr);
- Declare Function dws_DetectHardWare(dr As
- dws_DETECTRESULTS) as Integer
- function dws_DetectHardWare(var dr: dws_DETECTRESULTS)
- : WORDBOOL;
- Description
- This function determines the capabilities of the hardware and drivers, and also
- calculates the WIN-STK's internal buffer size.
-
- If there is more than one audio device or device driver, the WIN-STK will
- choose the most capable: 16-bit is chosen over 8-bit, stereo over mono, and
- higher sampling rates over lower.
- Notes
- You may call this function only before dws_Init, or again after dws_Kill.
- Parameters
- dr ptr to struct to hold the calculated information
- Related Functions
- dws_Init
- Errors
- dws_ALREADYINITTED, dws_INTERNALERROR,
- dws_INVALIDPOINTER, dws_MEMORYALLOCFAILED,
- dws_RESOURCEINUSE, dws_SETEVENTFAILED
-
- dws_DGetInfo
- Declarations
- WORD dws_DGetInfo(dws_DPLAY *dp1, dws_DPLAY *dp2);
- Declare Function dws_DGetInfo(dp1 As dws_DPLAY,
- dp2 As dws_DPLAY) As Integer
- function dws_DGetInfo(var dp1: dws_DPLAYREC; var dp2:
- dws_DPLAYREC) : WORDBOOL;
- Description
- This function returns information about a playing sound, and the one sequenced
- to play after it.
- Parameters
- dp1 ptr to struct to hold information on currently-playing sound
- dp2 the same, for sequenced sound
-
- The flags field in each struct is used to specify which fields to query. You
- must indicate which sound is of interest, by using the soundnum field in at
- least one struct. If you initialize the soundnum field in both structs, then both
- must be the same (e.g. dp1->soundnum = dp2->soundnum). This is
- because a sequenced sound always has the same sound ID number as the
- playing sound.
-
- You may query these fields: dws_dplay_SND, dws_dplay_COUNT,
- dws_dplay_PRIORITY, dws_dplay_PRESND, dws_dplay_LVOL,
- dws_dplay_RVOL, dws_dplay_PITCH, or dws_dplay_CALLBACK.
-
- If dws_dplay_CALLBACK is specified, then both the hwndmsg and the
- message fields are returned.
- Related Functions
- dws_DPlay, dws_DSetInfo
- Errors
- dws_D_BADDPLAY, dws_INVALIDPOINTER, dws_NOTINITTED,
- dws_NOTSUPPORTED
-
- dws_DGetRateFromDWD
- Declarations
- WORD dws_DGetRateFromDWD(BYTE *snd, WORD *rate);
- Declare Function dws_DGetRateFromDWD(snd As Long,
- rate As Integer) As Integer
- function dws_DGetRateFromDWD(snd: PBYTE; var rate:
- WORD) : WORDBOOL;
- Description
- This function returns the sampling rate of the specified DWD.
- Notes
- You may call this function at any time, even before dws_Init, or after
- dws_Kill.
- Parameters
- snd ptr to the DWD of interest
- rate variable which will hold the returned sampling rate, in Hz
- Related Functions
- dws_Init, dws_WAV2DWD
- Errors
- dws_D_NOTADWD, dws_D_NOTSUPPORTEDVER,
- dws_INVALIDPOINTER
-
- dws_DPause
- Declarations
- WORD dws_DPause(void);
- Declare Function dws_DPause() As Integer
- function dws_DPause : WORDBOOL;
- Description
- This function pauses all digitized playback.
-
- Note: all calls after the first will have no effect until dws_DUnPause is called.
- The WIN-STK does not maintain a "pause count".
- Parameters
- None.
- Related Functions
- dws_DUnPause
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_DPlay
- Declarations
- WORD dws_DPlay(dws_DPLAY *dplay);
- Declare Function dws_DPlay(dplay As dws_DPLAY) As
- Integer
- function dws_DPlay(var dplay: dws_DPLAYREC) :
- WORDBOOL;
- Description
- This function can play or sequence a sound.
-
- "Sequencing" a sound causes it to play after another specified sound is done.
-
- The dws_dplay_SYNCHRONOUS flag causes it to wait til the sound is done.
- Parameters
- dplay ptr to struct specifying the sound
- Note
- Most of the fields in the dplay struct are optional; you must set the
- corresponding bit in the flags field to indicate which ones you're using.
-
- Each field (except flags and snd) gets a reasonable default if not specified:
- count = 1
- priority = dws_NORMALPRIORITY
- presnd = (none)
- lvol = dws_IDENTITY
- rvol = dws_IDENTITY
- pitch = dws_IDENTITY
- hwndmsg = (none)
- message = (none)
- Related Functions
- dws_DClear, dws_DDiscard, dws_DDiscardAO, dws_DGetInfo,
- dws_DSetInfo
- Errors
- dws_D_BADDPLAY, dws_D_NOTSUPPORTEDVER,
- dws_DPlay_NOSPACEFORSOUND, dws_INVALIDPOINTER,
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_DSetInfo
- Declarations
- WORD dws_DSetInfo(dws_DPLAY *dp1, dws_DPLAY *dp2);
- Declare Function dws_DSetInfo(dp1 As dws_DPLAY, dp2 As
- dws_DPLAY) As Integer
- function dws_DSetInfo(var dp1: dws_DPLAYREC; var dp2:
- dws_DPLAYREC) : WORDBOOL;
- Description
- This function can change the parameters of a playing sound, and the one
- sequenced to play after it.
- Parameters
- dp1 ptr to struct which holds new parameters for currently playing sound
- dp2 the same, for sequenced sound
- Note
- The flags field in each struct is used to specify which fields to modify. You
- must indicate which sound is of interest, by using the soundnum field in at
- least one struct. If you initialize the soundnum field in both structs, then both
- must be the same (e.g. dp1->soundnum = dp2->soundnum). This is
- because a sequenced sound always has the same sound ID number as the
- playing sound.
-
- The following parameters may be changed dws_dplay_COUNT,
- dws_dplay_PRIORITY, dws_dplay_LVOL, dws_dplay_RVOL,
- dws_dplay_PITCH, and dws_dplay_CALLBACK.
-
- If you specify dws_dplay_CALLBACK then be sure to fill in both the
- hwndmsg and the message field.
- Related Functions
- dws_DGetInfo, dws_DPlay
- Errors
- dws_D_BADDPLAY, dws_INVALIDPOINTER, dws_NOTINITTED,
- dws_NOTSUPPORTED
-
- dws_DUnPause
- Declarations
- WORD dws_DUnPause(void);
- Declare Function dws_DUnPause() As Integer
- function dws_DUnPause : WORDBOOL;
- Description
- This function resumes digitized playback, if it was previously paused by
- dws_DPause.
-
- All sounds will continue where they left off.
-
- Note: all calls after the first will have no effect until dws_DPause is called
- again. The WIN-STK does not maintain a "pause count".
- Parameters
- None.
- Related Functions
- dws_DPause
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_ErrNo
- Declarations
- WORD dws_ErrNo(void);
- Declare Function dws_ErrNo() As Integer
- function dws_ErrNo : WORD;
- Description
- This function returns the last error triggered by a WIN-STK function. Call it
- after any WIN-STK function returns failure (0 or FALSE).
-
- Successful WIN-STK calls do not affect the return value of dws_ErrNo.
- Notes
- You may call this function at any time, even before dws_Init, or after
- dws_Kill.
- Parameters
- None.
- Related Functions
- All.
- Errors
- None.
-
- dws_Init
- Declarations
- WORD dws_Init(dws_DETECTRESULTS *dr, dws_IDEAL
- *ideal);
- Declare Function dws_Init(dr As dws_DETECTRESULTS,
- ideal As dws_IDEAL) As Integer
- function dws_Init(var dr: dws_DETECTRESULTS; var
- ideal: dws_IDEAL) : WORDBOOL;
- Description
- This function configures and initializes the sound device drivers and the WIN-
- STK internals. Most STK calls won't work until after this call.
-
- The exceptions are dws_DetectHardWare, dws_DGetRateFromDWD,
- dws_ErrNo, and dws_WAV2DWD.
- Parameters
- dr ptr to struct which holds the output from dws_DetectHardWare
- ideal ptr to struct specifying some WIN-STK mode parameters
- Related Functions
- dws_DetectHardWare, dws_Kill
- Errors
- dws_ALREADYINITTED, dws_Init_BUFTOOSMALL,
- dws_INTERNALERROR, dws_INVALIDPOINTER,
- dws_MEMORYALLOCFAILED, dws_NOTSUPPORTED,
- dws_RESOURCEINUSE, dws_SETEVENTFAILED
-
- dws_Kill
- Declarations
- WORD dws_Kill(void);
- Declare Function dws_Kill() As Integer
- function dws_Kill : WORDBOOL;
- Description
- This function kills the WIN-STK.
-
- If you have successfully called dws_Init, then you must call this function
- before your program terminates.
- Parameters
- None.
- Related Functions
- dws_Init
- Errors
- dws_NOTINITTED
-
- dws_MClear
- Declarations
- WORD dws_MClear(void);
- Declare Function dws_MClear() As Integer
- function dws_MClear : WORDBOOL;
- Description
- This function kills the music playback.
- Parameters
- None.
- Related Functions
- dws_MPlay
- Errors
- dws_INTERNALERROR, dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_MPause
- Declarations
- WORD dws_MPause(void);
- Declare Function dws_MPause() As Integer
- function dws_MPause : WORDBOOL;
- Description
- This function pauses music playback.
-
- Note: all calls after the first will have no effect until dws_MUnPause is called.
- The WIN-STK does not maintain a "pause count".
- Parameters
- None.
- Related Functions
- dws_MUnPause
- Errors
- dws_NOTSUPPORTED, dws_NOTINITTED
-
- dws_MPlay
- Declarations
- WORD dws_MPlay(dws_MPLAY *mplay);
- Declare Function dws_MPlay(mplay As dws_MPlay) As
- Integer
- function dws_MPlay(var mplay: dws_MPLAYREC) :
- WORDBOOL;
- Description
- This function starts playing a MIDI song. For WIN-STK version 1, the MIDI
- song must be played from disk. Version 2 will play from a memory buffer.
- Notes
- When specifying the MIDI filename, be sure to use the full pathname.
- Parameters
- mplay ptr to struct specifying the song
- Related Functions
- dws_MPause, dws_MSongStatus
- Errors
- dws_INTERNALERROR, dws_INVALIDPOINTER, dws_NOTINITTED,
- dws_NOTSUPPORTED, dws_M_BADMPLAY
-
- dws_MSongStatus
- Declarations
- WORD dws_MSongStatus(WORD *result);
- Declare Function dws_MSongStatus(result As Integer) As
- Integer
- function dws_MSongStatus(var result: WORD) : WORDBOOL;
- Description
- This function returns the status of the music playback engine.
- Parameters
- result ptr to a variable to hold the returned status:
-
- 0 //no song loaded
- dws_MSONGSTATUSPLAYING //song playing
- dws_MSONGSTATUSPAUSED //no song loaded, STK paused
- dws_MSONGSTATUSPLAYING | dws_MSONGSTATUSPAUSED //Song
- loaded but paused
- Related Functions
- dws_MPause, dws_MPlay, dws_MUnPause
- Errors
- dws_INVALIDPOINTER, dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_MUnPause
- Declarations
- WORD dws_MUnPause(void);
- Declare Function dws_MUnPause() As Integer
- function dws_MUnPause : WORDBOOL;
- Description
- This function resumes music playback, if it was previously paused by
- dws_MPause.
-
- The music will continue where it left off.
-
- Note: all calls after the first will have no effect until dws_MPause is called
- again. The WIN-STK does not maintain a "pause count".
- Parameters
- None.
- Related Functions
- dws_MPause
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- dws_Update
- Declarations
- WORD dws_Update(void);
- Declare Function dws_Update() As Integer
- function dws_Update : WORDBOOL;
- Description
- This function keeps the digitized sound going, even if your application is
- hogging the CPU. Under normal circumstances, calling this function shouldn't
- be necessary with the 32-bit WIN-STK DLL. In a 16-bit program, on the other
- hand, you may need to call dws_Update to prevent sound skipping, unless
- you are scrupulous about yielding time to the system frequently. We
- recommend an interval of 55ms (18.2 Hz).
- Notes
- The Windows API timeSetEvent can be used to give you a callback during
- each hardware timer interrupt. During such callbacks, most Windows API calls
- are off-limits; Windows is not reentrant. dws_Update makes function calls
- which are in this category. Calling it from an interrupt-time callback will crash
- Windows!
- Parameters
- None.
- Related Functions
- None.
- Errors
- dws_NOTINITTED
-
- dws_WAV2DWD
- Declarations
- WORD dws_WAV2DWD(BYTE *wave, DWORD *len, BYTE *dwd);
- Declare Function dws_WAV2DWD(wave As Long, len As
- Long, dwd As Long) As Integer
- function dws_WAV2DWD(wave: PBYTE; var len: DWORD; snd:
- PBYTE) : WORDBOOL;
- Description
- This function can convert a WAV-format buffer to DWD-format. DWD is the
- digitized sound format used by DiamondWare's Sound ToolKit.
- Notes
- There are two usages of this function. The first returns the buffer length
- required to hold the DWD. The second converts the WAV to DWD format.
- Notes
- You may call this function at any time, even before dws_Init, or after
- dws_Kill.
- Parameters
- Usage 1
- wave ptr to buffer containing a valid WAV file
- len length of the WAV buffer
- dwd NULL
- Usage 2
- wave ptr to WAV buffer
- len length of the WAV (input), size of DWD (output)
- dwd ptr to a buffer to hold the DWD output
- Related Functions
- dws_DGetRateFromDWD, dws_DPlay
- Errors
- dws_INTERNALERROR, dws_INVALIDPOINTER,
- dws_WAV2DWD_NOTAWAVE, dws_WAV2DWD_UNSUPPORTEDFORMAT
-
- dws_XDig
- Declarations
- WORD dws_XDig(WORD lvolume, WORD rvolume);
- Declare Function dws_XDig(ByVal lvolume As Integer,
- ByVal rvolume As Integer) As Integer
- function dws_XDig(lvolume, rvolume: WORD) : WORDBOOL;
- Description
- This function allows you to control the overall volume for digitized sound
- output.
- Parameters
- lvolume left volume, 0=off, dws_IDENTITY=normal, 65535=MAX
- rvolume same, for right channel
- Related Functions
- dws_DPlay
- Errors
- dws_NOTINITTED, dws_NOTSUPPORTED
-
- The Errors
- There are 16 errors (plus one non-error) which may be generated by a WIN-
- STK function.
-
- 0 dws_EZERO
- This is a non-error. dws_ErrNo will return this if you call it before any WIN-
- STK function triggers an error.
-
- 1 dws_NOTINITTED
- The STK was not initialized when you called an STK function.
-
- 2 dws_ALREADYINITTED
- This call cannot be made after the STK is initialized.
-
- 3 dws_NOTSUPPORTED
- The installed hardware, or current WIN-STK mode doesn't support the
- requested feature (music or sound).
-
- 4 dws_INTERNALERROR
- The STK encountered an invalid internal state. Please report this to
- DiamondWare.
-
- 5 dws_INVALIDPOINTER
- You passed an invalid pointer to a function. Under Win32, the WIN-STK can
- sometimes catch this type of problem and trigger an error.
-
- 6 dws_RESOURCEINUSE
- The WIN-STK tried to open a device driver, but it was already opened by
- another program.
-
- 7 dws_MEMORYALLOCFAILED
- The WIN-STK tried to allocate some memory, but was denied.
-
- 8 dws_SETEVENTFAILED
- The WIN-STK tried to set an event semaphore, but was denied.
-
- 9 dws_BUSY
- The WIN-STK is currently processing something; please try your call again
- later. This error can only occur in 16-bit programs, and if you're calling the
- WIN-STK from an interrupt handler or equivalent. The error cannot occur in
- 32-bit programs, because the WIN-STK is thread-safe.
-
-
- 101 dws_Init_BUFTOOSMALL
- You tried to set the buffer size in the dws_IDEAL struct to something which
- was obviously too small.
-
- 201 dws_D_NOTADWD
- The DWD buffer you passed did not contain a DWD file.
-
- 202 dws_D_NOTSUPPORTEDVER
- The DWD buffer you passed contained an unknown or unsupported version of
- DWD file.
-
- 203 dws_D_BADDPLAY
- You set up a dws_DPLAY struct which was not valid for the function called.
-
- Note: dws_DGetInfo and dws_DSetInfo require the soundnum field to
- specify the sound.
-
- 251 dws_DPlay_NOSPACEFORSOUND
- This is more of a warning than an error. It's telling you that there are no sound
- slots left, and that the priority of your new sound was too low to displace any
- playing sound.
-
- 301 dws_WAV2DWD_NOTAWAVE
- The WAV buffer you passed did not contain a WAV file.
-
- 302 dws_WAV2DWD_UNSUPPORTEDFORMAT
- The WAV buffer you passed contained an unknown or unsupported version of
- WAV file.
-
- 401 dws_M_BADMPLAY
- You set up a dws_MPLAY struct which was not valid for the function called.
-
-
- The Data Structures
- There are 4 structure types provided by the WIN-STK. Their formats and
- specifications are detailed here.
- dws_DETECTRESULTS
- This struct is filled in by dws_DetectHardWare. The digbfr field is user-
- writable, but use caution.
-
- Note: information is stored in the reserved field. If you're writing this struct
- out to a file, make sure to write out the entire contents. Failure to do this may
- result in unpredictable behavior!
-
- Name Size Description
- muscaps 4 *bitwise OR of available music devices
- digcaps 4 +bitwise OR of available WAV modes
- digbfr 4 buffer size calculated by autodetect
- reserved 20 undocumented
-
- *The music devices are dws_muscap_MIDIPORT (external MIDI port, MPU-
- 401 adapter or compatible, wavetable board, etc.), dws_muscap_SYNTH (a
- generic internal synthesizer), dws_muscap_SQSYNTH (a square-wave synth),
- dws_muscap_FMSYNTH (FM synthesizer), and dws_muscap_MAPPER (the
- MIDI mapper). If there is no MIDI capability installed in the machine, then the
- muscaps field will be set to dws_muscap_NONE.
-
- +The WAV modes are dws_digcap_11025_08_1,
- dws_digcap_11025_08_2, dws_digcap_11025_16_1,
- dws_digcap_11025_16_2, dws_digcap_22050_08_1,
- dws_digcap_22050_08_2, dws_digcap_22050_16_1,
- dws_digcap_22050_16_2, dws_digcap_44100_08_1,
- dws_digcap_44100_08_2, dws_digcap_44100_16_1, and
- dws_digcap_44100_16_2. If there is no WAV capability in the machine,
- then the digcaps field will be set to dws_digcap_NONE.
-
- The format of each constant is dws_digcap_<sampling rate in Hz>_<bits per
- sample>_<number of channels> (e.g. dws_digcap_22050_08_2 for 22kHz
- 8-bit stereo).
- dws_IDEAL
- This struct allows you to control the mode and features that the WIN-STK will
- set up when it initializes.
-
- Name Size Description
- flags 4 *bitwise OR of options
- mustyp 4 preferred MIDI device
- digtyp 4 preferred WAV output mode
- dignvoices 2 max digitized voices to mix
- reserved 18 undocumented
-
- *The possible flags are dws_ideal_SWAPLR (if the left and right channels
- are reversed by the hardware, the WIN-STK can swap them to compensate),
- dws_ideal_DISABLEPITCH (for extra speed, disable pitch changing on
- slow machines with one simple flag), dws_ideal_DISABLEVOLUME (for
- even more speed, disable volume changing), and dws_ideal_MAXSPEED (a
- shortcut to disable the pitch and volume change feature). Specify
- dws_ideal_NONE if you don't want any of these options.
- dws_DPLAY
- This struct is used for playing or sequencing a digitized sound (the dws_DPlay
- function). It's also used for querying a playing or sequenced sound (the
- dws_DGetInfo function) and reprogramming a playing or sequenced sound
- (the dws_DSetInfo function).
-
- Name Size Description
- flags 4 *bitfield specifying fields used
- snd 4 pointer to DWD buffer
- count 2 number of times to play; 0=infinite
- priority 2 +higher numbers = higher priorities
- presnd 2 soundnum of sound to sequence after
- soundnum 2 number assigned to this sound
- lvol 2 left volume, 0-dws_IDENTITY-65535
- rvol 2 the same, for the right channel
- pitch 2 #playback length
- dummy 2 pads next field to dword boundary
- hwndmsg ^4 =handle of window to send msgs to
- message ^4 message ID to send
- reserved ^18 undocumented
-
- *There is a bitfield flag corresponding to each field in this struct, except that
- hwndmsg and message must be specified as a pair, and so get only one flag.
- Additionally, some flags directly control functional behavior, and so do not
- correspond to any field in the struct. The flags are dws_dplay_SND,
- dws_dplay_COUNT, dws_dplay_PRIORITY, dws_dplay_PRESND,
- dws_dplay_SOUNDNUM, dws_dplay_LVOL, dws_dplay_RVOL,
- dws_dplay_PITCH, dws_dplay_CALLBACK,
- dws_dplay_SYNCHRONOUS, dws_dplay_FIRSTSAMPLE,
- dws_dplay_CURSAMPLE, and dws_dplay_LASTSAMPLE. For each field
- in the struct you use, set the corresponding bit in flags.
-
- +If the program tries to play more sounds than specified in the dws_IDEAL
- struct passed to dws_Init, then the lowest priority sound will be dropped.
-
- #The pitch field actually controls the playback length. In other words, lower
- values mean higher frequencies, and higher values mean lower (and slower)
- playback. As with volume change, dws_IDENTITY means no change in
- volume.
-
- ^Sizes are given for the 32-bit DLL. For the 16-bit DLL, hwndmsg and
- message are both 2 bytes. reserved is 22 bytes.
-
- =When the WIN-STK send you a window message, the wParam parameter
- holds the soundnum, and lParam holds dws_event_SOUNDCOMPLETE,
- dws_event_SOUNDSTARTED, or dws_event_SOUNDABORTED.
- dws_MPLAY
- This struct is used for playing a MIDI song by the dws_MPlay function.
-
- Name Size Description
- track 4 0-terminated filename of MIDI song
- count 2 number of times to play; 0=infinite
- reserved 10 undocumented
-
- The Utilities
- We provide two utilities, PLAYSTK (with source in C, Visual BASIC, and
- Pascal) and WAV2DWD. Both include 16- and 32-bit versions.
- PLAYSTK
- PLAYSTK is provided mostly as a source-code example of how to use the
- WIN-STK. It's also useful as a test to see if the machine is working. It can play
- several digitized sounds (.WAV or .DWD format) plus a song (.MID format) at
- the same time.
-
- It's implemented as a dialog box. On the right side are sliders for volume and
- pitch control. These affect all new sounds played, and they'll also change the
- most recent currently playing sound. There is a check box to reverse the left
- and right channels. And there are three radio buttons to control sampling rate.
- The program is hard-wired for 8-bit stereo output.
-
- The New button will bring up a dialog box which allows you to open any
- .WAV, .DWD, or .MID file.
-
- The Play button will start whichever sound or song is selected in the listbox.
- Double-clicking on a listbox item will also play it.
-
- The Stop button will stop all noise.
-
- The Remove button will delete the selected listbox item.
-
- Operation should be straightforward and intuitive. The source code shows you
- many WIN-STK programming techniques.
- WAV2DWD
- This program is provided to make batch conversion of a large number of WAV
- files easy. The WIN-STK can convert WAV buffers to DWD at runtime. But if
- you know what files you need in advance, then converting them off-line is the
- best way to go.
-
- This program is implemented as a dialog box.
-
- There are three windows on the left side to control the source (WAV) file
- selections. They are drive, directory, and file listboxes. The three windows on
- the right side control drive and directory for the output (DWD) plus show
- (without any user control) the list of DWD files in the output directory.
-
- Once you've set up your source and destination directories, select one or more
- WAV files to convert. Hit the Convert button, and DWD files quickly appear.
-
- 8-bit mono WAVs convert to DWDs which are also suitable for use with the
- DOS-STK.
-
- The File Formats
- WIN-STK version 1 uses one file format specified by DiamondWare. It's called
- DWD (DiamondWare Digitized).
-
- The specification is provided here in the hope that it may be useful to you.
- Permission is hereby granted to use this specification in the creation of any
- software. The specification itself is, of course, protected by United States law
- and international treaty provisions.
- DWD Header
- Byte # Description
- 00-22 "DiamondWare Digitized\n\0"
- 23 1A (EOF to abort printing of file)
- 24 Major version number
- 25 Minor version number
- 26-29 Unique sound ID (checksum XOR timestamp)
- 30 Reserved
- 31 Compression type (0=none)
- 32-33 Sampling rate (in Hz)
- 34 Number of channels (1=mono, 2=stereo)
- 35 Number of bits per sample (8, 16)
- 36-37 Absolute value of largest sample in file
- 38-41 length of data section (in bytes)
- 42-45 # samples (16-bit stereo is 4 bytes/sample)
- 46-49 Offset of data from start of file (in bytes)
- 50-53 Reserved for future expansion (markers)
- 54-55 Padding
- ??-?? Future expansion (heed the 2 offsets, above!)
- About DWD Version Numbers
- The DWD specification v1.0, finalized in 1994, did not need modification to
- support the WIN-STK. However, due to a slight oversight, the DOS-STK does
- not reject DWD files which are stereo and/or 16-bit, even though it cannot
- correctly play them (there was no software which could generate such files back
- then). We can't recall that product, so we are incrementing the version # of the
- file.
-
- 8-bit mono DWD files with no compression should be marked as version 1.0.
- The DOS- or WIN-STK can correctly play these files. If a DWD file contains
- two (or more) channels, 16 (or more) bits per sample, or compression, then it
- must be marked as version 1.1, which will be rejected by the DOS-STK. Our
- WAV2DWD utility generates files according to this version numbering scheme.
-
- The WIN-STK will attempt to play any file of version 1.x (unlike the DOS-
- STK). Any future enhancements to the file format which break backwards
- compatibility will jump to 2.0 or higher for this reason.
- Sample Format
- Samples are stored as signed data. That is, each 8-bit sample ranges from -128
- to +127. 16-bit samples range from -32768 to +32767.
-
- Monophonic files are stored in order, from sample 0 to sample N.
-
- Stereophonic files are stored in order, with the left channel of each sample
- preceding the right.
-
- DWD File Format Clarification, September 8, 1996
- Starting at byte 56, and continuing to the offset of the sound data (which is
- specified in the DWORD at bytes 46-49), there is room for additional text
- information fields (e.g. title, copyright, comments, etc.)
-
- So long as the offset-to-data field is correct, all code written to play or
- parse DWD files (going back to the DOS-STK v1.0) will continue to work
- correctly.
-
- Each text string in this new section must be NULL-terminated, and the entire
- section should itself be NULL-terminated. Also, just like the environment-
- variable model from which this borrows, each string will be of the format:
- <name>=value.
-
- In all fields which might contain multiple names (e.g. keywords, editor), we
- recommend that you separate each value with a semicolon and a space (e.g. Bob
- Miller; John Smith). It will help, with such digital editors as CoolEdit.
- For the same reason, do not use any newlines.
-
- Each of the following fields is optional, and may occur in any order:
-
- TITLE
- This brief name should describe the digital sound, but be short enough for
- display in a listbox.
- ORGARTIST
- The name of the author of the original sound, before digital editing.
- GENRE
- Metal, jazz, classical, instrument, sound effect, etc.
- KEYWORDS
- For searching.
- DIGSRC
- Describe the source format (e.g. AAD CD), digitizer used (e.g. SB 16), etc.
- ORGMEDIUM
- Voice, orchestra, industral site, etc.
- EDITOR
- The name(s) of the editor(s) who worked on the file, or edited it in any way.
- Give credit where credit is due.
- DIGITIZER
- The name of the person who digitized the file.
- COMMENT
- Please end each sentence with a period.
- SUBJECT
- Describes the subject matter recorded.
- SRC
- The source of the sound: a record label, studio engineer, or whomever
- actually recorded it.
- COPYRIGHT
- Example: Copyright 1996, DiamondWare, Ltd. All Rights Reserved.
- SOFTWARE
- The program used to edit this file.
- CREATEDATE
- The date of the original recording. Use yyyy-mm-dd format (e.g. 1996-09-08).
-
- Appendix
- Changes from the Sound ToolKit for DOS
- If you have used DiamondWare's Sound ToolKit for DOS, you may wish to
- skim most of the manual and study this section.
-
- In all cases we have attempted to preserve the same API and behavior as in the
- DOS version. Some changes, many bona fide enhancements, were required or
- made possible by the move to Windows.
-
- We'll go over the changes to the data structures, functions, behavior, errors,
- samples, and utility software.
- Data Structures
- Note: we changed all occurrences of byte, word, and dword to BYTE,
- WORD, and DWORD, to conform to the Windows convention.
- Pascal Note
- The DOS-STK used explicit pointer syntax. The WIN-STK now uses the var
- keyword.
- dws_DETECTOVERRIDES
- In Windows, the sound driver deals with the port, DMA, and IRQ settings, so
- the STK doesn't need to try to autodetect them. This struct was originally
- provided to override the autodetect, and has been completely eliminated in the
- WIN-STK.
- dws_DETECTRESULTS
- Forget everything you learned about this structure under DOS. Its purpose is
- still the same: to store the results of the autodetect. But under Windows, we're
- detecting buffer size, driver and hardware capabilities, not hardware settings.
-
- You might want to read about this structure in the Reference section.
- dws_IDEAL
- digrate has been merged into digtyp, which is now a bitfield. Read the
- section on the dws_IDEAL struct for details on how this works.
-
- In Windows, there is often a choice of music output devices (with different
- levels of sound quality). The muscaps field in the dws_DETECTRESULTS
- struct tells you which drivers are installed. The mustyp field in the
- dws_IDEAL struct allows you to specify which one to use.
-
- There is now a flags field, which allows you to disable volume and/or pitch
- changing support (for slower machines). It also allows you to specify that the
- left and right channels should be swapped (to compensate for wiring problems
- downstream).
- dws_DPLAY
- This structure has been greatly expanded, due to the integration of volume/pitch
- change functionality into the kernel, and the new support for stereo.
-
- You should set the first field, flags, to indicate which of the rest of the fields
- you're using. In most cases, unused fields will assume reasonable defaults--see
- the complete discussion in the Reference section for details.
-
- snd, count, priority, presnd, and soundnum work as they did in the
- DOS version.
-
- We added lvol and rvol to control the left and right volume of the sound.
-
- Note: Both mono and stereo source sounds will play in stereo, so long as the
- output mode is stereo.
-
- pitch controls the playback rate of the sound. More specifically, it controls
- the length of the sound during playback. Thus higher numbers correspond to
- slower and lower sounds, and lower numbers correspond to faster and higher
- sounds.
-
- For normal playback, use dws_IDENTITY for lvol, rvol, and pitch.
-
- The WIN-STK can notify you when a sound is done playing. For this feature,
- use the last two fields: hwndmsg and message. The WIN-STK will send
- message ID message to the window whose handle is hwndmsg. In this
- message, the wParam parameter holds the soundnum, and the lParam
- parameter holds dws_event_SOUNDCOMPLETE (future versions will support
- more types of events).
- dws_MPLAY
- The track field is now a NULL-terminated string holding the filename of the
- MIDI song to play (future versions will again play music from memory buffers).
- Functions
- We removed some functions, added a few new ones, and changed one.
- Removed
- dws_DGetRate
- dws_DSetRate
- dws_DSoundStatus
- dws_XMaster
- dws_XMusic
- dwt_*
-
- The playback rate cannot be changed while the STK is running under Windows.
- However, the built-in DSP can compensate for the odd sound recorded at a
- different sampling rate (there will be some sound quality loss, however).
-
- dws_DSoundStatus has been replaced with dws_DGetInfo, which is
- much more powerful. This function pairs well with dws_DSetInfo.
-
- In Windows, the user can change the mixer volumes at will using the control
- panel. Therefore, it's unnecessary (and counter to the Windows paradigm) for
- an application to gratuitously change them. Thus, we've eliminated
- dws_XMaster and dws_XMusic. Below, read what we've done with
- dws_XDig.
-
- Because implementing a timer like the DWT is trivial in Windows, and because
- the WIN-STK doesn't require you to call dws_Update frequently and
- periodically (see below), we're no longer providing the DWT.
- Added
- dws_DGetInfo
- dws_DSetInfo
- dws_WAV2DWD
-
- dws_DGetInfo will return you a full dws_DPLAY structure full of
- information about a playing or sequenced sound. You can change most of the
- fields, and then call dws_DSetInfo. See the Reference section for details.
-
- dws_WAV2DWD allows you to convert WAV files to DWD format at runtime.
- Changed
- dws_Update
- dws_XDig
-
- In the DOS-STK, dws_Update kept the music playing; if you didn't call it,
- you didn't get music. We provided the optional DWT module to take care of
- this, or you could call it from your own hardware time handler. All of this stuff
- is unnecessary in Windows.
-
- But Windows (version 3.x) causes other problems. Each application runs until it
- voluntarily yields time to the system and other applications. "Normal"
- applications are supposed to play nicely, and yield frequently. If an application
- hogs the system, all other apps (and the Windows GUI) freeze until the hog
- yields. This is bad enough (though often tolerated) with productivity
- applications. But it's totally unacceptable for sound to stop and then resume
- playing a quarter-second later. The discontinuity jars the listener.
-
- Games and multimedia applications can generally assume that they're not
- sharing the system with email, word processors, spreadsheets, etc. But they do
- often spend significant time in tight loops, and sometimes it's quite inconvenient
- to yield time to the system.
-
- If your Windows 3.x application needs to hog the system for a while, call
- dws_Update periodically; we recommend an interval of 55ms (18.2 times per
- second). This will keep the sound rolling under 3.x (the only way to stop it is to
- drag your application by the title bar). Under 95/NT, the 32-bit version of the
- WIN-STK is multithreaded, though the function is fully enabled, and works as it
- does under 16 bits.
-
- dws_XDig no longer controls the hardware mixer. Instead, it controls our
- internal software mixer. Thus, it makes it easy to quickly lower or raise (subject
- to clipping distortion) the overall digitized volume level. dws_XMusic (and
- dws_XMaster) will return with WIN-STK v2, which will provide much
- greater control over MIDI music.
-
- dws_XDig now takes two parameters, to support stereo. And these parameters
- are 0 to 256 (dws_IDENTITY) to 65535, rather than 0-255 in the DOS version.
- The ability to make digitized playback louder via dws_XDig is new for the
- WIN-STK.
- Behavior
- Some changes in behavior are noted above in the discussions of the various data
- structures and functions. Below, in no particular order, are some other changes
- of which you should be aware.
-
- In the DOS-STK, the digitized buffer size was a purely internal issue. Our
- research and testing determined the buffer size. We compiled it into the STK,
- and it just worked. Unfortunately, under Windows, the buffer size must change
- from system to system. Why? Because larger buffers are less susceptible to
- skipping, but smaller buffers provide lower latency (the time between the call to
- dws_DPlay and when the user actually hears the sound). Slower machines
- therefore require larger buffers. Buffer size determination is a non-trivial
- calculation, which is performed during dws_DetectHardWare. You might
- provide your user a slider bar with some amount of control over buffer size, to
- optimize on his machine the tradeoff between latency and skipless playback.
-
- After the call to dws_DetectHardWare, you can change digbfr slightly
- (go easy!) according to the user's input. Of course, most of the time, the
- autodetect routine will do its job properly, and you won't need to monkey with
- this setting. Unless there's a problem with skipping, leave it alone.
-
- The DOS version dropped low-priority sounds out when the dynamic range of
- the hardware would otherwise be exceeded. The WIN-STK can clip sounds on
- a sample-by-sample basis. Each sound must still have a priority so that if the
- maximum number of sounds is exceeded, the kernel knows in which order to
- drop sounds.
-
- The DOS version supported only 8-bit mono sound. The WIN-STK supports 8-
- and 16-bit source sounds in both mono and stereo, and can play using drivers in
- 8- or 16-bit, mono or stereo modes. It will perform all necessary conversions.
-
- The DOS version was restricted to sounds smaller than 64K. Both the 16- and
- 32-bit WIN-STK DLLs support sounds up to 4G in length.
-
- The 32-bit WIN-STK DLL can trap exceptions caused by invalid user-supplied
- pointers, and flag them with an error return value.
-
- For WIN-STK version 1, music is played directly from .MID files on disk.
- Version 2 will play from memory and provide interactivity and runtime control
- of music. Therefore, we say a temporary goodbye to the .DWM file (it will
- return!) There is also no control of FM-instrument patches with the WIN-STK.
- Errors
- Many errors are unnecessary under Windows, and have been eliminated. We've
- added some new ones too. As with the DOS version, the main manual lists all
- possible errors which can be flagged by each routine.
-
- You might want to read the Error listing in the Reference section.
- Samples
- PLAYSTK.C
- PLAYSTK.BAS
- PLAYSTK.PAS
-
- The samples all compile into PLAY16.EXE or PLAY32.EXE, which is a single
- sample applet for both music and sound.
- Utility Programs
- We eliminated VOC2DWD.EXE (VOC files are dying along with DOS) and
- MID2DWM.EXE (this version of the WIN-STK does not use .DWM files).
-
- We now provide WAV2DWD.EXE, which functionality is also available to
- your application on-line via the WIN-STK library.
-