AudioDetect.cc revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1993-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <malloc.h>
#include <stdlib.h>
#include <memory.h>
#include <AudioBuffer.h>
#include <AudioLib.h>
#include <AudioDetect.h>
#include <silence_detect.h>
// XXX - temporary: manual data conversion
#include <AudioTypePcm.h>
// class AudioDetectArray methods
// Allocation increment for array
static const unsigned int ARRAY_INCR = 50;
// Minimum time for detection algorithm is 250 milliseconds
static const double MIN_DURATION = .250;
// The detection algorithm needs at least 20 msecs more than silence duration
static const double DURATION_INCR = .022;
// Minimum silence for detection algorithm is fine grain
// XXX - not used for now
static const double MIN_SILENCE = .05;
// Constructor
unsigned int cnt): // start size of array
count(0)
{
if (size == 0)
}
// Destructor
{
}
// Append a list of detection points to the array
unsigned int cnt) // number of points to append
{
// If cnt == -1, append until eof
if (cnt == -1) {
cnt = 1;
cnt++;
cp++;
}
}
// Loop through, appending each new point in turn
while (cnt-- > 0) {
// Time to allocate more space in array
size += ARRAY_INCR;
pts = (AudioDetectPts*)
return (AUDIO_UNIXERROR);
}
}
return (AUDIO_SUCCESS);
}
// Process the detection array, eliminating eofs and collapsing adjacent entries
void AudioDetectArray::
reduce()
{
unsigned int ocnt; // output counter
// Start input and output pointers together
ocnt = 0;
// If no entries in the array, make at least one
if (count == 0) {
count = 1;
return;
}
// Get a legitimate starting point
}
if (count <= 0) {
return;
}
// Copy first entry
ocnt++;
count--;
// Collapse the array
while (count-- > 0) {
// Eliminate adjacent entries of same type
ip++;
// Remove non-final eofs
ip++;
} else {
ocnt++;
}
}
}
// Copy the detection array to a new array
{
// Allocate new array of adequate size
return (AUDIO_UNIXERROR);
// Copy array
return (AUDIO_SUCCESS);
}
// class AudioDetect methods
// Constructor
{
min_sound = .3;
min_silence = .2;
}
// Destructor
~AudioDetect()
{
}
// Get parameters for the audio detection algorithm.
// Each call retrieves one parameter. The parameter is identified
// by the 'type' argument. 'Valp' is a pointer to the new value.
{
switch (type) {
case DETECT_MINIMUM_SILENCE:
val = min_silence;
break;
case DETECT_MINIMUM_SOUND:
break;
case DETECT_THRESHOLD_SCALE:
val = thresh_scale;
break;
case DETECT_NOISE_RATIO:
val = noise_ratio;
break;
default:
return (AUDIO_ERR_BADARG);
}
return (AUDIO_SUCCESS);
}
// Set parameters for the audio detection algorithm.
// Each call adjusts one parameter. The parameter is identified
// by the 'type' argument. 'Valp' is a pointer to the new value.
{
if (val < 0.)
return (AUDIO_ERR_BADARG);
switch (type) {
case DETECT_MINIMUM_SILENCE:
min_silence = val;
break;
case DETECT_MINIMUM_SOUND:
break;
case DETECT_THRESHOLD_SCALE:
thresh_scale = val;
break;
case DETECT_NOISE_RATIO:
if (val > 1.)
return (AUDIO_ERR_BADARG);
noise_ratio = val;
break;
default:
return (AUDIO_ERR_BADARG);
}
return (AUDIO_SUCCESS);
}
// Entry stubs for invocations with missing arguments
{
}
{
}
// Process data from a given Audio object, filling in the 'vals' structure.
// If from and to identify a subset region for which there are
// already valid markers in the 'vals' structure, 'vals' is updated.
// For instance, suppose a 60 second file has already been mapped out.
// Now a PASTE operation inserts 10 seconds right in the middle.
// Step through the vals structure, adding 10 (the insert length) to
// every time greater than 30 (the insert point). Then call this routine
// with (from, to) set to (30, 40). The vals structure will be
// updated by reading the minimum required amount of data (which will,
// however, be a little longer than 10 seconds in order to get the
// transitions right).
// Returns audio error code or AUDIO_SUCCESS.
// This routine deallocates the input copy of 'pts', so make sure
// it is a copy of non-volatile storage, if necessary.
{
unsigned int cnt;
ap = new AudioDetectArray;
return (AUDIO_UNIXERROR);
// Get largest of the minimum time parameters
maxdur += DURATION_INCR;
if (maxdur < MIN_DURATION)
// Adjust starting time
if (from < 0.)
from = 0.;
// Adjust ending time
// If replacing virtually the whole array, skip trying to update
from = 0.;
}
// If time is a subset of an existing list, copy out the first entries
cnt = 0;
cnt++;
list++;
}
goto error_ret;
}
// Analyze the specified region of data
goto error_ret;
// If time is a subset of an existing list, copy out the last entries
list++;
}
}
}
// Compress and copy the list
// Eliminate silence segments that are under their length threshold
}
// Eliminate sound segments that are under their length threshold
}
// Caller must free the returned array
// XXX - maybe can arrange for caller to dup it instead
// Throw away interim structures
delete ap;
return (err);
}
// Audio detection main anaylze loop
{
unsigned int bufsiz;
unsigned int npts;
int i;
int valid;
END_POINTS* ep;
offset = 0;
// Start out assuming non-silence
return (err);
// If eof, set an eof marker
goto no_data;
}
// Init detection state
// Loop while there is data to read
do {
// If eof, we're done
break;
}
// If the current sample rate does not match the old, re-init
buf->Dereference();
// Allocate a new holding buffer
return (AUDIO_UNIXERROR);
goto error_ret;
// Update algorithm state
}
// Limit the copy to the buffer length or remaining data time
}
}
// Copy one region of data
// XXX - Duplicate bufptr to hold onto it (for now)
// tmpend should = 0. from initialization area
// tmpend should be cleared each time before calling.
// Bug ID 4034048 DPT 24-Feb-97
tmpend = 0.;
// XXX - Temporary: Convert to linear manually
if (!err) {
// only convert if not LINEAR pcm
if (!err)
} else {
}
}
if (!err) {
// Process data through signal detection routine
if (i == SILENCE_ERR_BUFFER_TOO_SMALL) {
// If buffer too small, go on
err = AUDIO_SUCCESS;
} else if (i == SILENCE_ERR_REALLOC_FAILED) {
}
// Convert endpoints to AudioDetectPts
if (!err) {
// First, add byte offset to all 'times'
// Then, create entries for silence regions
for (i = 0; i < npts; i++) {
goto error_ret;
// If the end of silence is the same
// as the end of processed data,
// don't start sound yet
break;
goto error_ret;
}
}
}
} while (!err);
// Set end-of-file marker to latest position
}
buf->Dereference();
return (err);
}