blob: e00f5652eb1bbf17e7120dcf15e6b0791255d551 [file] [log] [blame]
Bill Coxca02d872010-11-02 15:10:52 -04001/* Sonic library
2 Copyright 2010
3 Bill Cox
4 This file is part of the Sonic Library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
19
20/*
21The Sonic Library implements Pitch Based Resampling, which is a new algorithm
22invented by Bill Cox for the specific purpose of speeding up speech by high
23factors at high quality. It generates smooth speech at speed up factors as high
24as 6X, possibly more. It is also capable of slowing down speech, and generates
25high quality results regardless of the speed up or slow down factor. For
26speeding up speech by 2X or more, the following equation is used:
27
28 newSamples = period/(speed - 1.0)
29 scale = 1.0/newSamples;
30
31where period is the current pitch period, determined using AMDF or any other
32pitch estimator, and speed is the speedup factor. If the current position in
33the input stream is pointed to by "samples", and the current output stream
34position is pointed to by "out", then newSamples number of samples can be
35generated with:
36
37 out[t] = (samples[t]*(newSamples - t) + samples[t + period]*t)/newSamples;
38
39where t = 0 to newSamples - 1.
40
41For speed factors < 2X, an algorithm similar to PICOLA is used. The above
42algorithm is first used to double the speed of one pitch period. Then, enough
43input is directly copied from the input to the output to achieve the desired
44speed up facter, where 1.0 < speed < 2.0. The amount of data copied is derived:
45
46 speed = (2*period + length)/(period + length)
47 speed*length + speed*period = 2*period + length
48 length(speed - 1) = 2*period - speed*period
49 length = period*(2 - speed)/(speed - 1)
50
51For slowing down speech where 0.5 < speed < 1.0, a pitch period is inserted into
52the output twice, and length of input is copied from the input to the output
53until the output desired speed is reached. The length of data copied is:
54
55 length = period*(speed - 0.5)/(1 - speed)
56
57For slow down factors between 0.5 and 0.5, no data is copied, and an algorithm
58similar to high speed factors is used.
59*/
60
61/* This specifies the range of voice pitches we try to match. */
62#define SONIC_MIN_PITCH 50
63#define SONIC_MAX_PITCH 400
64
65struct sonicStreamStruct;
66typedef struct sonicStreamStruct *sonicStream;
67
68/* Create a sonic stream. Return NULL only if we are out of memory and cannot
69 allocate the stream. */
70sonicStream sonicCreateStream(double speed, int sampleRate);
71/* Destroy the sonic stream. */
72void sonicDestroyStream(sonicStream stream);
73/* Use this to write data to be speed up or down into the stream. Return 0 if
74 memory realloc failed, otherwise 1 */
75int sonicWriteToStream(sonicStream stream, float *samples, int numSamples);
76/* Use this to read data out of the stream. Sometimes no data will be
77 available, and zero is returned, which is not an error condition. */
78int sonicReadFromStream(sonicStream stream, float *samples, int maxSamples);
79/* Force the sonic stream to generate output using whatever data it currently
80 has. Zeros will be appended to the input data if there is not enough data
81 in the stream's input buffer. Use this, followed by a final read from the
82 stream before destroying the stream. */
83int sonicFlushStream(sonicStream stream);
84/* Return the number of samples in the output buffer */
85int sonicSamplesAvailale(sonicStream stream);