xref: /haiku/src/apps/cortex/addons/common/SoundUtils.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2  * Copyright 1998-1999, Be Incorporated.
3  * Copyright (c) 1999-2000, Eric Moon.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions, and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
28  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 
33 /*******************************************************************************
34 /
35 /	File:			SoundUtils.cpp
36 /
37 /   Description:	Utility functions for handling audio data.
38 /
39 *******************************************************************************/
40 
41 #include "SoundUtils.h"
42 
43 #include <cmath>
44 
45 // These two conversions seem to pop up all the time in media code.
46 // I guess it's the curse of microsecond resolution... ;-)
47 double
48 us_to_s(bigtime_t usecs)
49 {
50 	return (usecs / 1000000.0);
51 }
52 
53 bigtime_t
54 s_to_us(double secs)
55 {
56 	return (bigtime_t) (secs * 1000000.0);
57 }
58 
59 int
60 bytes_per_frame(
61 	const media_raw_audio_format & format)
62 {
63 	//	The media_raw_audio_format format constants encode the
64 	//	bytes-per-sample value in the low nybble. Having a fixed
65 	//	number of bytes-per-sample, and no inter-sample relationships,
66 	//	is what makes a format "raw".
67 	int bytesPerSample = format.format & 0xf;
68 	return bytesPerSample * format.channel_count;
69 }
70 
71 int
72 frames_per_buffer(
73 	const media_raw_audio_format & format)
74 {
75 	// This will give us the number of full-sized frames that will fit
76 	// in a buffer. (Remember, integer division automatically rounds
77 	// down.)
78 	int frames = 0;
79 	if (bytes_per_frame(format) > 0) {
80 		frames = format.buffer_size / bytes_per_frame(format);
81 	}
82 	return frames;
83 }
84 
85 bigtime_t
86 buffer_duration(
87 	const media_raw_audio_format & format)
88 {
89 	//	Figuring out duration is easy. We take extra precaution to
90 	//	not divide by zero or return irrelevant results.
91 	bigtime_t duration = 0;
92 	if (format.buffer_size > 0 && format.frame_rate > 0 && bytes_per_frame(format) > 0) {
93 		//	In these kinds of calculations, it's always useful to double-check
94 		//	the unit conversions. (Anyone remember high school physics?)
95 		//	bytes/(bytes/frame) / frames/sec
96 		//	= frames * sec/frames
97 		//	= secs                            which is what we want.
98 		duration = s_to_us((format.buffer_size / bytes_per_frame(format)) / format.frame_rate);
99 	}
100 	return duration;
101 }
102 
103 bigtime_t
104 frames_duration(
105 	const media_raw_audio_format & format, int64 num_frames)
106 {
107 	//	Tells us how long in us it will take to produce num_frames,
108 	//	with the given format.
109 	bigtime_t duration = 0;
110 	if (format.frame_rate > 0) {
111 		duration = s_to_us(num_frames/format.frame_rate);
112 	}
113 	return duration;
114 }
115 
116 int
117 buffers_for_duration(
118 	const media_raw_audio_format & format, bigtime_t duration)
119 {
120 	// Double-checking those unit conversions again:
121 	// secs * ( (frames/sec) / (frames/buffer) ) = secs * (buffers/sec) = buffers
122 	int buffers = 0;
123 	if (frames_per_buffer(format) > 0) {
124 		buffers = (int) ceil(us_to_s(duration)*(format.frame_rate/frames_per_buffer(format)));
125 	}
126 	return buffers;
127 }
128 
129 int64
130 frames_for_duration(
131 	const media_raw_audio_format & format, bigtime_t duration)
132 {
133 	return (int64) ceil(format.frame_rate*us_to_s(duration));
134 }
135