xref: /haiku/src/apps/mediaplayer/media_node_framework/audio/AudioReader.cpp (revision fb3e35fcec1ef41b413b3b121764509f436dee4d)
1 /*
2  * Copyright © 2000-2006 Ingo Weinhold <ingo_weinhold@gmx.de>
3  * All rights reserved. Distributed under the terms of the MIT licensce.
4  */
5 #include <algorithm>
6 #include <string.h>
7 
8 #include "AudioReader.h"
9 
10 using std::swap;
11 
12 
AudioReader()13 AudioReader::AudioReader()
14 	: fFormat(),
15 	  fOutOffset(0)
16 {
17 }
18 
19 
AudioReader(const media_format & format)20 AudioReader::AudioReader(const media_format& format)
21 	: fFormat(format),
22 	  fOutOffset(0)
23 {
24 }
25 
26 
~AudioReader()27 AudioReader::~AudioReader()
28 {
29 }
30 
31 
32 status_t
InitCheck() const33 AudioReader::InitCheck() const
34 {
35 	return B_OK;
36 }
37 
38 
39 void
SetFormat(const media_format & format)40 AudioReader::SetFormat(const media_format& format)
41 {
42 	fFormat = format;
43 }
44 
45 
46 const media_format&
Format() const47 AudioReader::Format() const
48 {
49 	return fFormat;
50 }
51 
52 
53 void
SetOutOffset(int64 offset)54 AudioReader::SetOutOffset(int64 offset)
55 {
56 	fOutOffset = offset;
57 }
58 
59 
60 int64
OutOffset() const61 AudioReader::OutOffset() const
62 {
63 	return fOutOffset;
64 }
65 
66 
67 int64
FrameForTime(bigtime_t time) const68 AudioReader::FrameForTime(bigtime_t time) const
69 {
70 	double frameRate = fFormat.u.raw_audio.frame_rate;
71 	return int64(double(time) * frameRate / 1000000.0);
72 }
73 
74 
75 bigtime_t
TimeForFrame(int64 frame) const76 AudioReader::TimeForFrame(int64 frame) const
77 {
78 	double frameRate = fFormat.u.raw_audio.frame_rate;
79 	return bigtime_t(double(frame) * 1000000.0 / frameRate);
80 }
81 
82 
83 //! helper function for ReadSilence()
84 template<typename sample_t>
85 inline void
fill_buffer(void * buffer,int32 count,sample_t value)86 fill_buffer(void* buffer, int32 count, sample_t value)
87 {
88 	sample_t* buf = (sample_t*)buffer;
89 	sample_t* bufferEnd = buf + count;
90 	for (; buf < bufferEnd; buf++)
91 		*buf = value;
92 }
93 
94 
95 /*! Fills the supplied buffer with /frames/ frames of silence and returns a
96 	pointer to the frames after the filled range.
97 	/frames/ must be >= 0.*/
98 void*
ReadSilence(void * buffer,int64 frames) const99 AudioReader::ReadSilence(void* buffer, int64 frames) const
100 {
101 	void* bufferEnd = SkipFrames(buffer, frames);
102 	int32 sampleCount = frames * fFormat.u.raw_audio.channel_count;
103 	switch (fFormat.u.raw_audio.format) {
104 		case media_raw_audio_format::B_AUDIO_FLOAT:
105 			fill_buffer(buffer, sampleCount, (float)0);
106 			break;
107 		case media_raw_audio_format::B_AUDIO_INT:
108 			fill_buffer(buffer, sampleCount, (int)0);
109 			break;
110 		case media_raw_audio_format::B_AUDIO_SHORT:
111 			fill_buffer(buffer, sampleCount, (short)0);
112 			break;
113 		case media_raw_audio_format::B_AUDIO_UCHAR:
114 			fill_buffer(buffer, sampleCount, (uchar)128);
115 			break;
116 		case media_raw_audio_format::B_AUDIO_CHAR:
117 			fill_buffer(buffer, sampleCount, (uchar)0);
118 			break;
119 		default:
120 			memset(buffer, 0, (char*)bufferEnd - (char*)buffer);
121 			break;
122  	}
123 	return bufferEnd;
124 }
125 
126 
127 //! Returns a buffer pointer offset by /frames/ frames.
128 void*
SkipFrames(void * buffer,int64 frames) const129 AudioReader::SkipFrames(void* buffer, int64 frames) const
130 {
131 	int32 sampleSize = fFormat.u.raw_audio.format
132 		& media_raw_audio_format::B_AUDIO_SIZE_MASK;
133 	int32 frameSize = sampleSize * fFormat.u.raw_audio.channel_count;
134 	return (char*)buffer + frames * frameSize;
135 }
136 
137 
138 void
ReverseFrames(void * buffer,int64 frames) const139 AudioReader::ReverseFrames(void* buffer, int64 frames) const
140 {
141 	int32 sampleSize = fFormat.u.raw_audio.format
142 		& media_raw_audio_format::B_AUDIO_SIZE_MASK;
143 	int32 frameSize = sampleSize * fFormat.u.raw_audio.channel_count;
144 	char* front = (char*)buffer;
145 	char* back = (char*)buffer + (frames - 1) * frameSize;
146 	while (front < back) {
147 		for (int32 i = 0; i < frameSize; i++)
148 			swap(front[i], back[i]);
149 		front += frameSize;
150 		back -= frameSize;
151 	}
152 }
153 
154