@@ -46,6 +46,9 @@ struct TensorInputPriv {
4646struct TensorOutputPriv {
4747 std::vector<sox_sample_t >* buffer;
4848};
49+ struct FileOutputPriv {
50+ sox_format_t * sf;
51+ };
4952
5053// / Callback function to feed Tensor data to SoxEffectChain.
5154int tensor_input_drain (sox_effect_t * effp, sox_sample_t * obuf, size_t * osamp) {
@@ -84,7 +87,7 @@ int tensor_input_drain(sox_effect_t* effp, sox_sample_t* obuf, size_t* osamp) {
8487
8588// / Callback function to fetch data from SoxEffectChain.
8689int tensor_output_flow (
87- sox_effect_t * effp LSX_UNUSED ,
90+ sox_effect_t * effp,
8891 sox_sample_t const * ibuf,
8992 sox_sample_t * obuf LSX_UNUSED,
9093 size_t * isamp,
@@ -97,6 +100,28 @@ int tensor_output_flow(
97100 return SOX_SUCCESS;
98101}
99102
103+ int file_output_flow (
104+ sox_effect_t * effp,
105+ sox_sample_t const * ibuf,
106+ sox_sample_t * obuf LSX_UNUSED,
107+ size_t * isamp,
108+ size_t * osamp) {
109+ *osamp = 0 ;
110+ if (*isamp) {
111+ auto sf = static_cast <FileOutputPriv*>(effp->priv )->sf ;
112+ if (sox_write (sf, ibuf, *isamp) != *isamp) {
113+ if (sf->sox_errno ) {
114+ std::ostringstream stream;
115+ stream << sf->sox_errstr << " " << sox_strerror (sf->sox_errno ) << " "
116+ << sf->filename ;
117+ throw std::runtime_error (stream.str ());
118+ }
119+ return SOX_EOF;
120+ }
121+ }
122+ return SOX_SUCCESS;
123+ }
124+
100125sox_effect_handler_t * get_tensor_input_handler () {
101126 static sox_effect_handler_t handler{/* name=*/ " input_tensor" ,
102127 /* usage=*/ NULL ,
@@ -125,6 +150,20 @@ sox_effect_handler_t* get_tensor_output_handler() {
125150 return &handler;
126151}
127152
153+ sox_effect_handler_t * get_file_output_handler () {
154+ static sox_effect_handler_t handler{/* name=*/ " output_file" ,
155+ /* usage=*/ NULL ,
156+ /* flags=*/ SOX_EFF_MCHAN,
157+ /* getopts=*/ NULL ,
158+ /* start=*/ NULL ,
159+ /* flow=*/ file_output_flow,
160+ /* drain=*/ NULL ,
161+ /* stop=*/ NULL ,
162+ /* kill=*/ NULL ,
163+ /* priv_size=*/ sizeof (FileOutputPriv)};
164+ return &handler;
165+ }
166+
128167} // namespace
129168
130169SoxEffectsChain::SoxEffectsChain (
@@ -134,6 +173,7 @@ SoxEffectsChain::SoxEffectsChain(
134173 out_enc_ (output_encoding),
135174 in_sig_(),
136175 interm_sig_(),
176+ out_sig_(),
137177 sec_(sox_create_effects_chain(&in_enc_, &out_enc_)) {
138178 if (!sec_) {
139179 throw std::runtime_error (" Failed to create effect chain." );
@@ -184,6 +224,17 @@ void SoxEffectsChain::addInputFile(sox_format_t* sf) {
184224 }
185225}
186226
227+ void SoxEffectsChain::addOutputFile (sox_format_t * sf) {
228+ out_sig_ = sf->signal ;
229+ SoxEffect e (sox_create_effect (get_file_output_handler ()));
230+ static_cast <FileOutputPriv*>(e->priv )->sf = sf;
231+ if (sox_add_effect (sec_, e, &interm_sig_, &out_sig_) != SOX_SUCCESS) {
232+ std::ostringstream stream;
233+ stream << " Failed to add effect: output " << sf->filename ;
234+ throw std::runtime_error (stream.str ());
235+ }
236+ }
237+
187238void SoxEffectsChain::addEffect (const std::vector<std::string> effect) {
188239 const auto num_args = effect.size ();
189240 if (num_args == 0 ) {
0 commit comments