tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / media / TrackReader.cpp
blobaa35a45b67fe5a40a86b1514525572576b34611e
1 /*
2 * Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files or portions
6 * thereof (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so, subject
10 * to the following conditions:
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright notice
16 * in the binary, as well as this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided with
18 * the distribution.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
31 * The undocumented BTrackReader class,
32 * used by BSound and the GameSound classes
35 #include <File.h>
36 #include <MediaTrack.h>
37 #include <MediaFile.h>
38 #include <string.h>
39 #include "TrackReader.h"
40 #include "debug.h"
42 namespace BPrivate
45 BTrackReader::BTrackReader(BMediaTrack *track, media_raw_audio_format const &format) :
46 fFrameSize(0),
47 fBuffer(0),
48 fBufferOffset(0),
49 fBufferUsedSize(0),
50 fMediaFile(0),
51 fMediaTrack(0),
52 fFormat(format)
54 CALLED();
55 if (track == NULL)
56 return;
57 if (track->InitCheck() != B_OK)
58 return;
60 SetToTrack(track);
62 // if the track was not set abort now
63 if (fMediaTrack == 0)
64 return;
66 fBuffer = new uint8[fFormat.buffer_size];
67 fFrameSize = fFormat.channel_count * (fFormat.format & media_raw_audio_format::B_AUDIO_SIZE_MASK);
69 TRACE("BTrackReader::BTrackReader successful\n");
73 BTrackReader::BTrackReader(BFile *file, media_raw_audio_format const &format) :
74 fFrameSize(0),
75 fBuffer(0),
76 fBufferOffset(0),
77 fBufferUsedSize(0),
78 fMediaFile(0),
79 fMediaTrack(0),
80 fFormat(format)
82 CALLED();
83 if (file == NULL)
84 return;
85 if (file->InitCheck() != B_OK)
86 return;
88 fMediaFile = new BMediaFile(file);
89 if (fMediaFile->InitCheck() != B_OK)
90 return;
92 int count = fMediaFile->CountTracks();
93 if (count == 0) {
94 ERROR("BTrackReader: no tracks in file\n");
95 return;
98 // find the first audio track
99 BMediaTrack *track;
100 BMediaTrack *audiotrack = 0;
101 for (int tr = 0; tr < count; tr++) {
102 track = fMediaFile->TrackAt(tr);
103 if (track == 0 || track->InitCheck() != B_OK)
104 continue;
105 media_format fmt;
106 if (track->DecodedFormat(&fmt) != B_OK)
107 continue;
108 if (fmt.type == B_MEDIA_RAW_AUDIO) {
109 audiotrack = track;
110 break;
112 fMediaFile->ReleaseTrack(track);
114 if (audiotrack == 0) {
115 ERROR("BTrackReader: no audio track in file\n");
116 return;
119 SetToTrack(audiotrack);
121 // if the track was not set, release it
122 if (fMediaTrack == 0) {
123 fMediaFile->ReleaseTrack(audiotrack);
124 return;
127 fBuffer = new uint8[fFormat.buffer_size];
128 fFrameSize = fFormat.channel_count * (fFormat.format & media_raw_audio_format::B_AUDIO_SIZE_MASK);
130 TRACE("BTrackReader::BTrackReader successful\n");
134 void
135 BTrackReader::SetToTrack(BMediaTrack *track)
137 media_format fmt;
138 memset(&fmt, 0, sizeof(fmt)); //wildcard
139 memcpy(&fmt.u.raw_audio, &fFormat, sizeof(fFormat));
140 fmt.type = B_MEDIA_RAW_AUDIO;
141 //try to find a output format
142 if (track->DecodedFormat(&fmt) == B_OK) {
143 memcpy(&fFormat, &fmt.u.raw_audio, sizeof(fFormat));
144 fMediaTrack = track;
145 return;
148 //try again
149 fmt.u.raw_audio.buffer_size = 2 * 4096;
150 fmt.u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
151 if (track->DecodedFormat(&fmt) == B_OK) {
152 memcpy(&fFormat, &fmt.u.raw_audio, sizeof(fFormat));
153 fMediaTrack = track;
154 return;
157 //try again
158 fmt.u.raw_audio.buffer_size = 4096;
159 fmt.u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
160 if (track->DecodedFormat(&fmt) == B_OK) {
161 memcpy(&fFormat, &fmt.u.raw_audio, sizeof(fFormat));
162 fMediaTrack = track;
163 return;
166 //we have failed
167 ERROR("BTrackReader::SetToTrack failed\n");
171 BTrackReader::~BTrackReader()
173 CALLED();
174 if (fMediaFile && fMediaTrack)
175 fMediaFile->ReleaseTrack(fMediaTrack);
176 delete fMediaFile;
177 delete[] fBuffer;
181 status_t
182 BTrackReader::InitCheck()
184 CALLED();
185 return fMediaTrack ? fMediaTrack->InitCheck() : B_ERROR;
189 int64
190 BTrackReader::CountFrames(void)
192 CALLED();
193 return fMediaTrack ? fMediaTrack->CountFrames() : 0;
197 const media_raw_audio_format &
198 BTrackReader::Format(void) const
200 CALLED();
201 return fFormat;
205 int32
206 BTrackReader::FrameSize(void)
208 CALLED();
209 return fFrameSize;
213 status_t
214 BTrackReader::ReadFrames(void* in_buffer, int32 frame_count)
216 CALLED();
218 uint8* buffer = static_cast<uint8*>(in_buffer);
219 int32 bytes_to_read = frame_count * fFrameSize;
221 status_t last_status = B_OK;
222 while (bytes_to_read > 0) {
223 int32 bytes_to_copy = min_c(fBufferUsedSize, bytes_to_read);
224 if (bytes_to_copy > 0) {
225 memcpy(buffer, fBuffer + fBufferOffset, bytes_to_copy);
226 buffer += bytes_to_copy;
227 bytes_to_read -= bytes_to_copy;
228 fBufferOffset += bytes_to_copy;
229 fBufferUsedSize -= bytes_to_copy;
231 if (last_status != B_OK)
232 break;
233 if (fBufferUsedSize == 0) {
234 int64 outFrameCount;
235 last_status = fMediaTrack->ReadFrames(fBuffer,
236 &outFrameCount);
237 fBufferOffset = 0;
238 fBufferUsedSize = outFrameCount * fFrameSize;
241 if (bytes_to_read > 0) {
242 memset(buffer, 0, bytes_to_read);
243 return B_LAST_BUFFER_ERROR;
245 return B_OK;
249 status_t
250 BTrackReader::SeekToFrame(int64* in_out_frame)
252 CALLED();
253 status_t s = fMediaTrack->SeekToFrame(in_out_frame, B_MEDIA_SEEK_CLOSEST_BACKWARD);
254 if (s != B_OK)
255 return s;
256 fBufferUsedSize = 0;
257 fBufferOffset = 0;
258 return B_OK;
262 BMediaTrack*
263 BTrackReader::Track(void)
265 CALLED();
266 return fMediaTrack;
269 }; //namespace BPrivate