~ubuntu-branches/ubuntu/hardy/alsa-plugins/hardy-proposed

« back to all changes in this revision

Viewing changes to pph/rate_speexrate.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2007-06-12 19:03:08 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070612190308-yhyjw8t4wk7zhte0
Tags: 1.0.14-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - debian/control:
    + Don't build-depend on JACK, as it's in universe.  Clarify and
      update the Description to note the above restriction and
      {in,ex}clusion of newer plugins (LP: #57089),
    + Adhere to DebianMaintainerField.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Rate converter plugin using Public Parrot Hack
 
2
   Copyright (C) 2007 Jean-Marc Valin
 
3
 
 
4
   Redistribution and use in source and binary forms, with or without
 
5
   modification, are permitted provided that the following conditions are
 
6
   met:
 
7
 
 
8
   1. Redistributions of source code must retain the above copyright notice,
 
9
   this list of conditions and the following disclaimer.
 
10
 
 
11
   2. Redistributions in binary form must reproduce the above copyright
 
12
   notice, this list of conditions and the following disclaimer in the
 
13
   documentation and/or other materials provided with the distribution.
 
14
 
 
15
   3. The name of the author may not be used to endorse or promote products
 
16
   derived from this software without specific prior written permission.
 
17
 
 
18
   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
19
   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
20
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 
22
   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
24
   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
25
   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
26
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
27
   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
28
   POSSIBILITY OF SUCH DAMAGE.
 
29
*/
 
30
 
 
31
#include <stdio.h>
 
32
#include <alsa/asoundlib.h>
 
33
#include <alsa/pcm_rate.h>
 
34
 
 
35
#ifdef USE_LIBSPEEX
 
36
#include <speex/speex_resampler.h>
 
37
#else
 
38
#include "speex_resampler.h"
 
39
#endif
 
40
 
 
41
struct rate_src {
 
42
        int quality;
 
43
        unsigned int channels;
 
44
        SpeexResamplerState *st;
 
45
};
 
46
 
 
47
static snd_pcm_uframes_t input_frames(void *obj, snd_pcm_uframes_t frames)
 
48
{
 
49
   spx_uint32_t num, den;
 
50
   struct rate_src *rate = obj;
 
51
   if (frames == 0)
 
52
      return 0;
 
53
   speex_resampler_get_ratio(rate->st, &num, &den);
 
54
   return (snd_pcm_uframes_t)((frames*num+(den>>1))/den);
 
55
}
 
56
 
 
57
static snd_pcm_uframes_t output_frames(void *obj, snd_pcm_uframes_t frames)
 
58
{
 
59
   spx_uint32_t num, den;
 
60
   struct rate_src *rate = obj;
 
61
   if (frames == 0)
 
62
      return 0;
 
63
   speex_resampler_get_ratio(rate->st, &num, &den);
 
64
   return (snd_pcm_uframes_t)((frames*den+(num>>1))/num);
 
65
}
 
66
 
 
67
static void pcm_src_free(void *obj)
 
68
{
 
69
   struct rate_src *rate = obj;
 
70
   if (rate->st)
 
71
   {
 
72
      speex_resampler_destroy(rate->st);
 
73
      rate->st = NULL;
 
74
   }
 
75
}
 
76
 
 
77
static int pcm_src_init(void *obj, snd_pcm_rate_info_t *info)
 
78
{
 
79
   struct rate_src *rate = obj;
 
80
   
 
81
   if (! rate->st || rate->channels != info->channels) {
 
82
      if (rate->st)
 
83
         speex_resampler_destroy(rate->st);
 
84
      rate->channels = info->channels;
 
85
      rate->st = speex_resampler_init_frac(rate->channels, info->in.period_size, info->out.period_size, info->in.rate, info->out.rate, rate->quality);
 
86
      if (! rate->st)
 
87
         return -EINVAL;
 
88
   }
 
89
 
 
90
   return 0;
 
91
}
 
92
 
 
93
static int pcm_src_adjust_pitch(void *obj, snd_pcm_rate_info_t *info)
 
94
{
 
95
   struct rate_src *rate = obj;
 
96
   speex_resampler_set_rate_frac(rate->st, info->in.period_size, info->out.period_size, info->in.rate, info->out.rate);
 
97
   return 0;
 
98
}
 
99
 
 
100
static void pcm_src_reset(void *obj)
 
101
{
 
102
   struct rate_src *rate = obj;
 
103
   speex_resampler_reset_mem(rate->st);
 
104
}
 
105
 
 
106
static void pcm_src_convert_s16(void *obj, int16_t *dst, unsigned int dst_frames,
 
107
                                const int16_t *src, unsigned int src_frames)
 
108
{
 
109
   struct rate_src *rate = obj;
 
110
   speex_resampler_process_interleaved_int(rate->st, src, &src_frames, dst, &dst_frames);
 
111
}
 
112
 
 
113
static void pcm_src_close(void *obj)
 
114
{
 
115
   free(obj);
 
116
}
 
117
 
 
118
static snd_pcm_rate_ops_t pcm_src_ops = {
 
119
        .close = pcm_src_close,
 
120
        .init = pcm_src_init,
 
121
        .free = pcm_src_free,
 
122
        .reset = pcm_src_reset,
 
123
        .adjust_pitch = pcm_src_adjust_pitch,
 
124
        .convert_s16 = pcm_src_convert_s16,
 
125
        .input_frames = input_frames,
 
126
        .output_frames = output_frames,
 
127
};
 
128
 
 
129
static int pcm_src_open(unsigned int version, void **objp,
 
130
                        snd_pcm_rate_ops_t *ops, int quality)
 
131
{
 
132
        struct rate_src *rate;
 
133
 
 
134
        if (version != SND_PCM_RATE_PLUGIN_VERSION) {
 
135
                fprintf(stderr, "Invalid rate plugin version %x\n", version);
 
136
                return -EINVAL;
 
137
        }
 
138
 
 
139
        rate = calloc(1, sizeof(*rate));
 
140
        if (! rate)
 
141
                return -ENOMEM;
 
142
        rate->quality = quality;
 
143
 
 
144
        *objp = rate;
 
145
        *ops = pcm_src_ops;
 
146
        return 0;
 
147
}
 
148
 
 
149
int SND_PCM_RATE_PLUGIN_ENTRY(speexrate) (unsigned int version, void **objp,
 
150
                                           snd_pcm_rate_ops_t *ops)
 
151
{
 
152
        return pcm_src_open(version, objp, ops, 3);
 
153
}
 
154
 
 
155
int SND_PCM_RATE_PLUGIN_ENTRY(speexrate_best) (unsigned int version, void **objp,
 
156
                                                snd_pcm_rate_ops_t *ops)
 
157
{
 
158
        return pcm_src_open(version, objp, ops, 10);
 
159
}
 
160
 
 
161
int SND_PCM_RATE_PLUGIN_ENTRY(speexrate_medium) (unsigned int version, void **objp,
 
162
                                                  snd_pcm_rate_ops_t *ops)
 
163
{
 
164
        return pcm_src_open(version, objp, ops, 5);
 
165
}