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... ;-)
47double
48us_to_s(bigtime_t usecs)
49{
50	return (usecs / 1000000.0);
51}
52
53bigtime_t
54s_to_us(double secs)
55{
56	return (bigtime_t) (secs * 1000000.0);
57}
58
59int
60bytes_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 & media_raw_audio_format::B_AUDIO_SIZE_MASK;
68	return bytesPerSample * format.channel_count;
69}
70
71int
72frames_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
85bigtime_t
86buffer_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
103bigtime_t
104frames_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
116int
117buffers_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
129int64
130frames_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