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