1/******************************************************************************
2/
3/	File:			SoundUtils.cpp
4/
5/   Description:	Utility functions for handling audio data.
6/
7/	Copyright 1998-1999, Be Incorporated, All Rights Reserved
8/
9******************************************************************************/
10
11#include <math.h>
12#include "SoundUtils.h"
13
14// These two conversions seem to pop up all the time in media code.
15// I guess it's the curse of microsecond resolution... ;-)
16double
17us_to_s(bigtime_t usecs)
18{
19	return (usecs / 1000000.0);
20}
21
22bigtime_t
23s_to_us(double secs)
24{
25	return (bigtime_t) (secs * 1000000.0);
26}
27
28int
29bytes_per_frame(
30	const media_raw_audio_format & format)
31{
32	//	The media_raw_audio_format format constants encode the
33	//	bytes-per-sample value in the low nybble. Having a fixed
34	//	number of bytes-per-sample, and no inter-sample relationships,
35	//	is what makes a format "raw".
36	int bytesPerSample = format.format & 0xf;
37	return bytesPerSample * format.channel_count;
38}
39
40int
41frames_per_buffer(
42	const media_raw_audio_format & format)
43{
44	// This will give us the number of full-sized frames that will fit
45	// in a buffer. (Remember, integer division automatically rounds
46	// down.)
47	int frames = 0;
48	if (bytes_per_frame(format) > 0) {
49		frames = format.buffer_size / bytes_per_frame(format);
50	}
51	return frames;
52}
53
54bigtime_t
55buffer_duration(
56	const media_raw_audio_format & format)
57{
58	//	Figuring out duration is easy. We take extra precaution to
59	//	not divide by zero or return irrelevant results.
60	bigtime_t duration = 0;
61	if (format.buffer_size > 0 && format.frame_rate > 0
62		&& bytes_per_frame(format) > 0) {
63		//	In these kinds of calculations, it's always useful to double-check
64		//	the unit conversions. (Anyone remember high school physics?)
65		//	bytes/(bytes/frame) / frames/sec
66		//	= frames * sec/frames
67		//	= secs                            which is what we want.
68		duration = s_to_us((format.buffer_size / bytes_per_frame(format))
69			/ format.frame_rate);
70	}
71	return duration;
72}
73
74bigtime_t
75frames_duration(
76	const media_raw_audio_format & format, int64 num_frames)
77{
78	//	Tells us how long in us it will take to produce num_frames,
79	//	with the given format.
80	bigtime_t duration = 0;
81	if (format.frame_rate > 0) {
82		duration = s_to_us(num_frames/format.frame_rate);
83	}
84	return duration;
85}
86
87int
88buffers_for_duration(
89	const media_raw_audio_format & format, bigtime_t duration)
90{
91	// Double-checking those unit conversions again:
92	// secs * ( (frames/sec) / (frames/buffer) ) = secs * (buffers/sec)
93	// = buffers
94	int buffers = 0;
95	if (frames_per_buffer(format) > 0) {
96		buffers = (int) ceil(us_to_s(duration)
97			*(format.frame_rate/frames_per_buffer(format)));
98	}
99	return buffers;
100}
101
102int64
103frames_for_duration(
104	const media_raw_audio_format & format, bigtime_t duration)
105{
106	return (int64) ceil(format.frame_rate*us_to_s(duration));
107}
108