~ubuntu-branches/ubuntu/jaunty/ecasound2.2/jaunty

« back to all changes in this revision

Viewing changes to libecasound/audioio-aac.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2005-04-14 09:15:48 UTC
  • Revision ID: james.westby@ubuntu.com-20050414091548-o7kgb47z0tcunh0s
Tags: upstream-2.4.1
ImportĀ upstreamĀ versionĀ 2.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ------------------------------------------------------------------------
 
2
// audioio-faad.cpp: Interface class for FAAC/FAAD AAC encoder/decoder.
 
3
// Copyright (C) 2004-2005 Kai Vehmanen
 
4
//
 
5
// Attributes:
 
6
//     eca-style-version: 3
 
7
//
 
8
// This program is free software; you can redistribute it and/or modify
 
9
// it under the terms of the GNU General Public License as published by
 
10
// the Free Software Foundation; either version 2 of the License, or
 
11
// (at your option) any later version.
 
12
// 
 
13
// This program is distributed in the hope that it will be useful,
 
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
// GNU General Public License for more details.
 
17
// 
 
18
// You should have received a copy of the GNU General Public License
 
19
// along with this program; if not, write to the Free Software
 
20
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
21
// ------------------------------------------------------------------------
 
22
 
 
23
#include <string>
 
24
#include <cstdlib> /* atol() */
 
25
#include <unistd.h> /* stat() */
 
26
#include <sys/stat.h> /* stat() */
 
27
 
 
28
#include <kvu_message_item.h>
 
29
#include <kvu_numtostr.h>
 
30
 
 
31
#include "audioio-aac.h"
 
32
 
 
33
#include "eca-logger.h"
 
34
 
 
35
/**
 
36
 * References:
 
37
 *    http://www.audiocoding.com/
 
38
 */
 
39
 
 
40
string AAC_FORKED_INTERFACE::default_input_cmd = "faad -w -b 1 -f 2 -d %f";
 
41
string AAC_FORKED_INTERFACE::default_output_cmd = "faac -P -o %f -R %s -B %b -C %c -";
 
42
 
 
43
void AAC_FORKED_INTERFACE::set_input_cmd(const std::string& value) { AAC_FORKED_INTERFACE::default_input_cmd = value; }
 
44
void AAC_FORKED_INTERFACE::set_output_cmd(const std::string& value) { AAC_FORKED_INTERFACE::default_output_cmd = value; }
 
45
 
 
46
AAC_FORKED_INTERFACE::AAC_FORKED_INTERFACE(const std::string& name)
 
47
{
 
48
  set_label(name);
 
49
  finished_rep = false;
 
50
}
 
51
 
 
52
AAC_FORKED_INTERFACE::~AAC_FORKED_INTERFACE(void)
 
53
{
 
54
  if (is_open() == true) {
 
55
    close();
 
56
  }
 
57
}
 
58
 
 
59
void AAC_FORKED_INTERFACE::open(void) throw (AUDIO_IO::SETUP_ERROR &)
 
60
{
 
61
  std::string urlprefix;
 
62
  triggered_rep = false;
 
63
 
 
64
  /**
 
65
   * FIXME: we have no idea about the audio format of the 
 
66
   *        stream we get from ogg123... maybe we should force decoder
 
67
   *        to generate RIFF wave to a named pipe and parse the header...?
 
68
   */
 
69
 
 
70
  if (io_mode() == io_read) {
 
71
    struct stat buf;
 
72
    int ret = ::stat(label().c_str(), &buf);
 
73
    if (ret != 0) {
 
74
      size_t offset = label().find_first_of("://");
 
75
      if (offset == std::string::npos) {
 
76
        throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-AAC: Can't open file " + label() + "."));
 
77
      }
 
78
      else {
 
79
        urlprefix = std::string(label(), 0, offset);
 
80
        ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-aac) Found url; protocol '" + urlprefix + "'.");
 
81
      }
 
82
    }
 
83
 
 
84
    /* decoder supports: fixed channel count and sample format, 
 
85
                         sample rate unknown and must be set manually  */
 
86
    set_channels(2); /* 5.1 downmixed to stereo if needed by faad2 */
 
87
    set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_be);
 
88
  }
 
89
  else {
 
90
    /* encoder supports: coding, channel-count and srate configurable;
 
91
       fixed endianess */
 
92
    set_sample_endianess(ECA_AUDIO_FORMAT::se_big);
 
93
  }
 
94
 
 
95
  AUDIO_IO::open();
 
96
}
 
97
 
 
98
void AAC_FORKED_INTERFACE::close(void)
 
99
{
 
100
  if (pid_of_child() > 0) {
 
101
      ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process." + kvu_numtostr(pid_of_child()) + ".");
 
102
      clean_child();
 
103
      triggered_rep = false;
 
104
  }
 
105
 
 
106
  AUDIO_IO::close();
 
107
}
 
108
 
 
109
long int AAC_FORKED_INTERFACE::read_samples(void* target_buffer, long int samples)
 
110
{
 
111
  if (triggered_rep != true) { 
 
112
    triggered_rep = true;
 
113
    fork_input_process();
 
114
  }
 
115
 
 
116
  if (f1_rep != 0) {
 
117
    bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, f1_rep);
 
118
  }
 
119
  else {
 
120
    bytes_rep = 0;
 
121
  }
 
122
 
 
123
  if (bytes_rep < samples * frame_size() || bytes_rep == 0) {
 
124
    if (position_in_samples() == 0) 
 
125
      ECA_LOG_MSG(ECA_LOGGER::info, "(audioio-aac) Can't start process \"" + AAC_FORKED_INTERFACE::default_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc.");
 
126
    finished_rep = true;
 
127
    triggered_rep = false;
 
128
  }
 
129
  else 
 
130
    finished_rep = false;
 
131
 
 
132
  return bytes_rep / frame_size();
 
133
}
 
134
 
 
135
void AAC_FORKED_INTERFACE::write_samples(void* target_buffer, long int samples)
 
136
{
 
137
  if (triggered_rep != true) {
 
138
    triggered_rep = true;
 
139
    fork_output_process();
 
140
  }
 
141
 
 
142
  if (wait_for_child() != true) {
 
143
    finished_rep = true;
 
144
    triggered_rep = false;
 
145
  }
 
146
  else {
 
147
    if (filedes_rep > 0) {
 
148
      bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples);
 
149
    }
 
150
    else {
 
151
      bytes_rep = 0;
 
152
    }
 
153
    if (bytes_rep < frame_size() * samples || bytes_rep == 0) {
 
154
      ECA_LOG_MSG(ECA_LOGGER::info, "(audioio-aac) Can't start process \"" + AAC_FORKED_INTERFACE::default_output_cmd + "\". FAAC v1.24 or newer is required. Please check your ~/.ecasound/ecasoundrc.");
 
155
      finished_rep = true;
 
156
      triggered_rep = false;
 
157
    }
 
158
    else finished_rep = false;
 
159
  }
 
160
}
 
161
 
 
162
void AAC_FORKED_INTERFACE::seek_position(void)
 
163
{
 
164
  if (pid_of_child() > 0) {
 
165
    ECA_LOG_MSG(ECA_LOGGER::user_objects, "(audioio-aac) Cleaning child process." + kvu_numtostr(pid_of_child()) + ".");
 
166
    clean_child();
 
167
    triggered_rep = false;
 
168
  }
 
169
  set_position_in_samples(0);
 
170
}
 
171
 
 
172
void AAC_FORKED_INTERFACE::set_parameter(int param, string value)
 
173
{
 
174
  switch (param) {
 
175
  case 1: 
 
176
    set_label(value);
 
177
    break;
 
178
  }
 
179
}
 
180
 
 
181
string AAC_FORKED_INTERFACE::get_parameter(int param) const
 
182
{
 
183
  switch (param) {
 
184
  case 1: 
 
185
    return label();
 
186
  }
 
187
  return "";
 
188
}
 
189
 
 
190
void AAC_FORKED_INTERFACE::fork_input_process(void)
 
191
{
 
192
  ECA_LOG_MSG(ECA_LOGGER::user_objects, AAC_FORKED_INTERFACE::default_input_cmd);
 
193
 
 
194
  set_fork_command(AAC_FORKED_INTERFACE::default_input_cmd);
 
195
  set_fork_file_name(label());
 
196
 
 
197
  fork_child_for_read();
 
198
  if (child_fork_succeeded() == true) {
 
199
    /* NOTE: the file description will be closed by 
 
200
     *       AUDIO_IO_FORKED_STREAM::clean_child() */
 
201
    filedes_rep = file_descriptor();
 
202
    f1_rep = fdopen(filedes_rep, "r"); /* not part of <cstdio> */
 
203
    if (f1_rep == 0) {
 
204
      finished_rep = true;
 
205
      triggered_rep = false;
 
206
    }
 
207
  }
 
208
  else
 
209
    f1_rep = 0;
 
210
}
 
211
 
 
212
void AAC_FORKED_INTERFACE::fork_output_process(void)
 
213
{
 
214
  string command = AAC_FORKED_INTERFACE::default_output_cmd;
 
215
 
 
216
  set_fork_command(command);
 
217
  set_fork_file_name(label());
 
218
 
 
219
  set_fork_bits(bits());
 
220
  set_fork_channels(channels());
 
221
  set_fork_sample_rate(samples_per_second());
 
222
 
 
223
  fork_child_for_write();
 
224
  if (child_fork_succeeded() == true) {
 
225
    filedes_rep = file_descriptor();
 
226
  }
 
227
  else {
 
228
    filedes_rep = 0;
 
229
  }
 
230
}