BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / audio / echo / generic / CDaffyDuck.h
blob6ed0daedf6409c263478068be89b2b1de47cba65
1 // ****************************************************************************
2 //
3 // CDaffyDuck.H
4 //
5 // Include file for interfacing with the CDaffyDuck class.
6 //
7 // A daffy duck maintains a scatter-gather list used by the DSP to
8 // transfer audio data via bus mastering.
9 //
10 // The scatter-gather list takes the form of a circular buffer of
11 // duck entries; each duck entry is an address/count pair that points
12 // to an audio data buffer somewhere in memory.
14 // Although the scatter-gather list itself is a circular buffer, that
15 // does not mean that the audio data pointed to by the scatter-gather
16 // list is necessarily a circular buffer. The audio buffers pointed to
17 // by the SG list may be either a non-circular linked list of buffers
18 // or a ring buffer.
20 // If you want a ring DMA buffer for your audio data, refer to the
21 // Wrap() method, below.
23 // The name "daffy duck" is an inside joke that dates back to the
24 // original VxD for Windows 95.
26 // Set editor tabs to 3 for your viewing pleasure.
28 //---------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
32 // This file is part of Echo Digital Audio's generic driver library.
33 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
34 // All rights reserved
35 // www.echoaudio.com
37 // This library is free software; you can redistribute it and/or
38 // modify it under the terms of the GNU Lesser General Public
39 // License as published by the Free Software Foundation; either
40 // version 2.1 of the License, or (at your option) any later version.
42 // This library is distributed in the hope that it will be useful,
43 // but WITHOUT ANY WARRANTY; without even the implied warranty of
44 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
45 // Lesser General Public License for more details.
47 // You should have received a copy of the GNU Lesser General Public
48 // License along with this library; if not, write to the Free Software
49 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51 // ****************************************************************************
53 // Prevent problems with multiple includes
55 #ifndef _DAFFYDUCKOBJECT_
56 #define _DAFFYDUCKOBJECT_
58 #ifdef _DEBUG
59 //#define INTEGRITY_CHECK
60 #endif
63 // DUCKENTRY is a single entry for the scatter-gather list. A DUCKENTRY
64 // struct is read by the DSP.
66 typedef struct
68 DWORD PhysAddr;
69 DWORD dwSize;
70 } DUCKENTRY, * PDUCKENTRY;
74 // The CDaffyDuck class keeps a parallel array of MAPPING structures
75 // that corresponds to the DUCKENTRY array. You can't just pack everything
76 // into one struct since the DSP reads the DUCKENTRY structs and wouldn't
77 // know what to do with the other fields.
79 typedef struct
81 NUINT Tag; // Unique ID for this mapping
82 ULONGLONG ullEndPos; // The cumulative 64-bit end position for this mapping
83 // = (previous ullEndPos) + (# of bytes mapped)
84 } MAPPING;
87 class CDspCommObject;
89 class CDaffyDuck
91 public:
94 // Number of entries in the circular buffer.
96 // If MAX_ENTRIES is set too high, SONAR crashes in Windows XP if you are
97 // using super-interleave mode. 64 seems to work.
99 enum
101 MAX_ENTRIES = 64, // Note this must be a power of 2
102 ENTRY_INDEX_MASK = MAX_ENTRIES-1
106 // Destructor
108 ~CDaffyDuck();
110 static CDaffyDuck * MakeDaffyDuck(COsSupport *pOsSupport);
112 protected:
115 // Protected constructor
117 CDaffyDuck(PCOsSupport pOsSupport);
119 DWORD m_dwPipeIndex;
121 PPAGE_BLOCK m_pDuckPage;
123 DUCKENTRY *m_DuckEntries; // Points to a locked physical page (4096 bytes)
124 // These are for the benefit of the DSP
125 MAPPING m_Mappings[MAX_ENTRIES];// Parallel circular buffer to m_DuckEntries;
126 // these are for the benefit of port class
128 DWORD m_dwHead; // Index where next mapping will be added;
129 // points to an empty slot
130 DWORD m_dwTail; // Next mapping to discard (read index)
131 DWORD m_dwCount; // Number of entries in the circular buffer
133 DWORD m_dwDuckEntriesPhys; // The DSP needs this - physical address
134 // of page pointed to by m_DuckEntries
136 ULONGLONG m_ullLastEndPos; // Used to calculate ullEndPos for new entries
138 PCOsSupport m_pOsSupport;
140 BOOL m_fWrapped;
142 #ifdef INTEGRITY_CHECK
143 void CheckIntegrity();
144 #endif
146 void EjectTail();
148 public:
150 void Reset();
152 void ResetStartPos();
155 // Call AddMapping to add a buffer of audio data to the scatter-gather list.
156 // Note that dwPhysAddr will be asserted on the PCI bus; you will need
157 // to make the appropriate translation between the virtual address of
158 // the page and the bus address *before* calling this function.
160 // The buffer must be physically contiguous.
162 // The Tag parameter is a unique ID for this mapping that is used by
163 // ReleaseUsedMapping and RevokeMappings; if you are building a circular
164 // buffer, the tag isn't important.
166 // dwInterrupt is true if you want the DSP to generate an IRQ after it
167 // consumes this audio buffer.
169 // dwNumFreeEntries is useful if you are calling this in a loop and
170 // want to know when to stop;
172 ECHOSTATUS AddMapping
174 DWORD dwPhysAddr,
175 DWORD dwBytes,
176 NUINT Tag, // Unique ID for this mapping
177 DWORD dwInterrupt, // Set TRUE if you want an IRQ after this mapping
178 DWORD &dwNumFreeEntries // Return value - number of slots left in the list
182 // AddDoubleZero is used to have the DSP generate an interrupt;
183 // calling AddDoubleZero will cause the DSP to interrupt after it finishes the
184 // previous duck entry.
186 ECHOSTATUS AddDoubleZero();
189 // Call Wrap if you are creating a circular DMA buffer; to make a circular
190 // double buffer, do this:
192 // AddMapping() Several times
193 // AddDoubleZero() First half-buffer interrupt
194 // AddMapping() Several more times
195 // AddDoubleZero() Second half-buffer interrupt
196 // Wrap() Wraps the scatter list around to make a circular buffer
198 // Once you call Wrap, you shouldn't add any more mappings.
200 void Wrap();
203 // Call ReleaseUsedMapping to conditionally remove the oldest duck entries.
205 // The return value is the number of tags written to the Tags array.
207 DWORD ReleaseUsedMappings
209 ULONGLONG ullDmaPos,
210 NUINT *Tags,
211 DWORD dwMaxTags
215 // Adjusts the duck so that DMA will start from a given position; useful
216 // when resuming from pause
218 void AdjustStartPos(ULONGLONG ullPos);
221 // This returns the physical address of the start of the scatter-gather
222 // list; used to tell the DSP where to start looking for duck entries.
224 DWORD GetPhysStartAddr();
227 // Any more room in the s.g. list?
229 DWORD GetNumFreeEntries()
231 return MAX_ENTRIES - m_dwCount;
235 // RevokeMappings is here specifically to support WDM; it removes
236 // any entries from the list if their tag is >= dwFirstTag and <= dwLastTag.
238 DWORD RevokeMappings
240 NUINT FirstTag,
241 NUINT LastTag
245 // Returns TRUE if Wrap has been called for this duck
247 BOOL Wrapped()
249 return m_fWrapped;
253 // CleanUpTail is used to clean out any non-audio entries from the tail
254 // of the list that might be left over from earlier
256 void CleanUpTail();
259 // Spew out some info
261 VOID DbgDump();
264 // Overload new & delete to make sure these objects are allocated from
265 // non-paged memory.
267 PVOID operator new( size_t Size );
268 VOID operator delete( PVOID pVoid );
270 }; // class CDaffyDuck
272 typedef CDaffyDuck * PCDaffyDuck;
274 #endif // _DAFFYDUCKOBJECT_
276 // *** CDaffyDuck.H ***