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