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
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
31 * The undocumented BTrackReader class,
32 * used by BSound and the GameSound classes
36 #include <MediaTrack.h>
37 #include <MediaFile.h>
39 #include "TrackReader.h"
45 BTrackReader::BTrackReader(BMediaTrack
*track
, media_raw_audio_format
const &format
) :
57 if (track
->InitCheck() != B_OK
)
62 // if the track was not set abort now
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
) :
85 if (file
->InitCheck() != B_OK
)
88 fMediaFile
= new BMediaFile(file
);
89 if (fMediaFile
->InitCheck() != B_OK
)
92 int count
= fMediaFile
->CountTracks();
94 ERROR("BTrackReader: no tracks in file\n");
98 // find the first audio 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
)
106 if (track
->DecodedFormat(&fmt
) != B_OK
)
108 if (fmt
.type
== B_MEDIA_RAW_AUDIO
) {
112 fMediaFile
->ReleaseTrack(track
);
114 if (audiotrack
== 0) {
115 ERROR("BTrackReader: no audio track in file\n");
119 SetToTrack(audiotrack
);
121 // if the track was not set, release it
122 if (fMediaTrack
== 0) {
123 fMediaFile
->ReleaseTrack(audiotrack
);
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");
135 BTrackReader::SetToTrack(BMediaTrack
*track
)
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
));
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
));
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
));
167 ERROR("BTrackReader::SetToTrack failed\n");
171 BTrackReader::~BTrackReader()
174 if (fMediaFile
&& fMediaTrack
)
175 fMediaFile
->ReleaseTrack(fMediaTrack
);
182 BTrackReader::InitCheck()
185 return fMediaTrack
? fMediaTrack
->InitCheck() : B_ERROR
;
190 BTrackReader::CountFrames(void)
193 return fMediaTrack
? fMediaTrack
->CountFrames() : 0;
197 const media_raw_audio_format
&
198 BTrackReader::Format(void) const
206 BTrackReader::FrameSize(void)
214 BTrackReader::ReadFrames(void* in_buffer
, int32 frame_count
)
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
)
233 if (fBufferUsedSize
== 0) {
235 last_status
= fMediaTrack
->ReadFrames(fBuffer
,
238 fBufferUsedSize
= outFrameCount
* fFrameSize
;
241 if (bytes_to_read
> 0) {
242 memset(buffer
, 0, bytes_to_read
);
243 return B_LAST_BUFFER_ERROR
;
250 BTrackReader::SeekToFrame(int64
* in_out_frame
)
253 status_t s
= fMediaTrack
->SeekToFrame(in_out_frame
, B_MEDIA_SEEK_CLOSEST_BACKWARD
);
263 BTrackReader::Track(void)
269 }; //namespace BPrivate