1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "stddsound.h"
19 #include "buffer_dsound.h"
20 #include "sound_driver_dsound.h"
30 using namespace NLMISC
;
35 static const std::string EmptyString
;
37 // Custom mutimedia IO proc.
38 /*LRESULT NelIOProc(LPSTR lpmmioinfo, UINT uMsg, LONG lParam1, LONG lParam2)
40 MMIOINFO *mmioinfo = (MMIOINFO*) lpmmioinfo;
46 // do some validity checking.
47 nlassert((mmioinfo->dwFlags & MMIO_CREATE) == 0);
49 char *fileName = (char*)lParam1;
50 std::string fullName = NLMISC::CPath::lookup(fileName, false);
53 mmioinfo->adwInfo[0] = NULL;
54 return MMIOERR_CANNOTOPEN;
57 NLMISC::CIFile *pfile = new NLMISC::CIFile(fullName);
59 mmioinfo->adwInfo[0] = (DWORD)pfile;
60 return MMSYSERR_NOERROR ;
65 NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
72 uint8 *pdst = (uint8*) lParam1;
73 uint bytes = (uint) lParam2;
75 nlassert(mmioinfo->adwInfo[0] != NULL);
76 NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
77 bytes = std::min(uint(file->getFileSize() - file->getPos()), bytes);
78 file->serialBufferWithSize(pdst, bytes);
80 mmioinfo->lBufOffset = file->getPos();
87 uint newPos = (uint) lParam1;
88 uint seekMode = lParam2;
90 nlassert(mmioinfo->adwInfo[0] != NULL);
91 NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
96 file->seek(newPos, NLMISC::IStream::current);
99 file->seek(newPos, NLMISC::IStream::end);
102 file->seek(newPos, NLMISC::IStream::begin);
106 mmioinfo->lBufOffset = file->getPos();
108 return mmioinfo->lBufOffset;
112 nlassert("Mutimedia IO write is not supported !");
114 case MMIOM_WRITEFLUSH:
115 nlassert("Mutimedia IO write is not supported !");
122 CBufferDSound::CBufferDSound() : _Data(NULL
), _Capacity(0), _Size(0)
124 _Name
= CStringMapper::map(EmptyString
);
129 CBufferDSound::~CBufferDSound()
131 // nldebug("Destroying DirectSound buffer %s (%p)", CSoundDriverDSound::instance()->getStringMapper()->unmap(_Name).c_str(), this);
140 void CBufferDSound::setName(NLMISC::TStringId bufferName
)
145 /// Set the sample format. (channels = 1, 2, ...; bitsPerSample = 8, 16; frequency = samples per second, 44100, ...)
146 void CBufferDSound::setFormat(TBufferFormat format
, uint8 channels
, uint8 bitsPerSample
, uint32 frequency
)
148 bufferFormatToSampleFormat(format
, channels
, bitsPerSample
, _Format
);
152 /// Get a writable pointer to the buffer of specified size. Returns NULL in case of failure. It is only guaranteed that the original data is still available when using StorageSoftware and the specified size is not larger than the available data. Call setStorageMode() and setFormat() first.
153 uint8
*CBufferDSound::lock(uint capacity
)
157 if (capacity
> _Capacity
)
166 _Data
= new uint8
[capacity
];
167 _Capacity
= capacity
;
168 if (_Size
> capacity
)
175 /// Notify that you are done writing to this buffer, so it can be copied over to hardware if needed. Returns true if ok.
176 bool CBufferDSound::unlock(uint size
)
178 if (size
> _Capacity
)
190 /// Copy the data with specified size into the buffer. A readable local copy is only guaranteed when OptionLocalBufferCopy is set. Returns true if ok.
191 bool CBufferDSound::fill(const uint8
*src
, uint size
)
193 uint8
*dest
= lock(size
);
194 if (dest
== NULL
) return false;
195 CFastMem::memcpy(dest
, src
, size
);
199 /// Return the sample format information.
200 void CBufferDSound::getFormat(TBufferFormat
&format
, uint8
&channels
, uint8
&bitsPerSample
, uint32
&frequency
) const
202 sampleFormatToBufferFormat(_Format
, format
, channels
, bitsPerSample
);
206 /// Return the size of the buffer, in bytes.
207 uint
CBufferDSound::getSize() const
212 float CBufferDSound::getDuration() const
214 float frames
= (float) _Size
;
234 return 1000.0f
* frames
/ (float) _Freq
;
237 bool CBufferDSound::isStereo() const
239 return (_Format
== Stereo8
) || (_Format
== Stereo16
);
242 /// Return the name of this buffer
243 NLMISC::TStringId
CBufferDSound::getName() const
248 /// Return true if the buffer is loaded. Used for async load/unload.
249 bool CBufferDSound::isBufferLoaded() const
251 return _Data
!= NULL
;
255 /// Set the storage mode of this buffer, call before filling this buffer. Storage mode is always software if OptionSoftwareBuffer is enabled. Default is auto.
256 void CBufferDSound::setStorageMode(TStorageMode
/* storageMode */)
258 // software buffering, no hardware storage mode available
261 /// Get the storage mode of this buffer.
262 IBuffer::TStorageMode
CBufferDSound::getStorageMode()
264 // always uses software buffers
265 return IBuffer::StorageSoftware
;