headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / media / Sound.cpp
blob711012264a71ab608adb27b44a8428272bd50fed
1 /*
2 * Copyright 2009, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Marcus Overhagen
7 * Michael Lotz <mmlr@mlotz.ch>
8 */
10 #include <Sound.h>
11 #include <File.h>
13 #include "TrackReader.h"
15 #include <debug.h>
16 #include <new>
17 #include <string.h>
20 BSound::BSound(void* data, size_t size, const media_raw_audio_format& format,
21 bool freeWhenDone)
22 : fData(data),
23 fDataSize(size),
24 fFile(NULL),
25 fRefCount(1),
26 fStatus(B_NO_INIT),
27 fFormat(format),
28 fFreeWhenDone(freeWhenDone),
29 fTrackReader(NULL)
31 if (fData == NULL)
32 return;
34 fStatus = B_OK;
38 BSound::BSound(const entry_ref* soundFile, bool loadIntoMemory)
39 : fData(NULL),
40 fDataSize(0),
41 fFile(new(std::nothrow) BFile(soundFile, B_READ_ONLY)),
42 fRefCount(1),
43 fStatus(B_NO_INIT),
44 fFreeWhenDone(false),
45 fTrackReader(NULL)
47 if (fFile == NULL) {
48 fStatus = B_NO_MEMORY;
49 return;
52 fStatus = fFile->InitCheck();
53 if (fStatus != B_OK)
54 return;
56 memset(&fFormat, 0, sizeof(fFormat));
57 fTrackReader = new(std::nothrow) BPrivate::BTrackReader(fFile, fFormat);
58 if (fTrackReader == NULL) {
59 fStatus = B_NO_MEMORY;
60 return;
63 fStatus = fTrackReader->InitCheck();
64 if (fStatus != B_OK)
65 return;
67 fFormat = fTrackReader->Format();
68 fStatus = B_OK;
72 BSound::BSound(const media_raw_audio_format& format)
73 : fData(NULL),
74 fDataSize(0),
75 fFile(NULL),
76 fRefCount(1),
77 fStatus(B_ERROR),
78 fFormat(format),
79 fFreeWhenDone(false),
80 fTrackReader(NULL)
82 // unimplemented protected constructor
83 UNIMPLEMENTED();
87 BSound::~BSound()
89 delete fTrackReader;
90 delete fFile;
92 if (fFreeWhenDone)
93 free(fData);
97 status_t
98 BSound::InitCheck()
100 return fStatus;
104 BSound*
105 BSound::AcquireRef()
107 atomic_add(&fRefCount, 1);
108 return this;
112 bool
113 BSound::ReleaseRef()
115 if (atomic_add(&fRefCount, -1) == 1) {
116 delete this;
117 return false;
120 // TODO: verify those returns
121 return true;
125 int32
126 BSound::RefCount() const
128 return fRefCount;
132 bigtime_t
133 BSound::Duration() const
135 UNIMPLEMENTED();
136 return 0;
140 const media_raw_audio_format&
141 BSound::Format() const
143 return fFormat;
147 const void*
148 BSound::Data() const
150 return fData;
154 off_t
155 BSound::Size() const
157 if (fFile != NULL) {
158 off_t result = 0;
159 fFile->GetSize(&result);
160 return result;
163 return fDataSize;
167 bool
168 BSound::GetDataAt(off_t offset, void* intoBuffer, size_t bufferSize,
169 size_t* outUsed)
171 if (intoBuffer == NULL)
172 return false;
174 if (fData != NULL) {
175 size_t copySize = MIN(bufferSize, fDataSize - offset);
176 memcpy(intoBuffer, (uint8*)fData + offset, copySize);
177 if (outUsed != NULL)
178 *outUsed = copySize;
179 return true;
182 if (fTrackReader != NULL) {
183 int32 frameSize = fTrackReader->FrameSize();
184 int64 frameCount = fTrackReader->CountFrames();
185 int64 startFrame = offset / frameSize;
186 if (startFrame > frameCount)
187 return false;
189 if (fTrackReader->SeekToFrame(&startFrame) != B_OK)
190 return false;
192 off_t bufferOffset = offset - startFrame * frameSize;
193 int64 directStartFrame = (offset + frameSize - 1) / frameSize;
194 int64 directFrameCount = (offset + bufferSize - directStartFrame
195 * frameSize) / frameSize;
197 if (bufferOffset != 0) {
198 int64 indirectFrameCount = directStartFrame - startFrame;
199 size_t indirectSize = indirectFrameCount * frameSize;
200 void* buffer = malloc(indirectSize);
201 if (buffer == NULL)
202 return false;
204 if (fTrackReader->ReadFrames(buffer, indirectFrameCount) != B_OK) {
205 free(buffer);
206 return false;
209 memcpy(intoBuffer, (uint8*)buffer + bufferOffset,
210 indirectSize - bufferOffset);
211 if (outUsed != NULL)
212 *outUsed = indirectSize - bufferOffset;
214 free(buffer);
215 } else if (outUsed != NULL)
216 *outUsed = 0;
218 if (fTrackReader->ReadFrames((uint8*)intoBuffer + bufferOffset,
219 directFrameCount) != B_OK)
220 return false;
222 if (outUsed != NULL)
223 *outUsed += directFrameCount * frameSize;
225 return true;
228 return false;
232 status_t
233 BSound::BindTo(BSoundPlayer* player, const media_raw_audio_format& format)
235 UNIMPLEMENTED();
236 return B_ERROR;
240 status_t
241 BSound::UnbindFrom(BSoundPlayer* player)
243 UNIMPLEMENTED();
244 return B_ERROR;
248 status_t
249 BSound::Perform(int32 code, ...)
251 UNIMPLEMENTED();
252 return B_ERROR;
256 status_t BSound::_Reserved_Sound_0(void*) { return B_ERROR; }
257 status_t BSound::_Reserved_Sound_1(void*) { return B_ERROR; }
258 status_t BSound::_Reserved_Sound_2(void*) { return B_ERROR; }
259 status_t BSound::_Reserved_Sound_3(void*) { return B_ERROR; }
260 status_t BSound::_Reserved_Sound_4(void*) { return B_ERROR; }
261 status_t BSound::_Reserved_Sound_5(void*) { return B_ERROR; }