Previous 15994 Revisions Next

r3148 Tuesday 2nd September, 2008 at 17:52:36 UTC by Antoine Mine
[THOMSON] speech synthesis improvements
[src/mess/audio]mea8000.c

src/mess/audio/mea8000.c
r3147r3148
1818  All parameters, including filter parameters, are smoothly interpolated
1919  for the duration of a frame (8ms, 16ms, 32ms, or 64 ms).
2020
21  IMPORTANT NOTE:
22  Emulation is not satisfactory and needs some work!
23  Control logics & quantisation tables seem OK.
24  However, the voice is terrible, you can barely recognise the words.
25  It may be a problem with the interpolation or the filtering logics.
26
2721  TODO:
28  - improve accuracy and sound quality!!!
2922  - REQ output pin
3023  - optimize mea8000_compute_sample
3124  - should we accept new frames in slow-stop mode ?
r3147r3148
247240}
248241
249242
243#ifndef FLOAT_MODE /* UINT16 version */
250244
251/* linear interpolation */
252static int mea8000_interp_i( UINT16 org, UINT16 dst )
253{
254   return org + (((dst-org) * mea8000.framepos) >> mea8000.framelog);
255}
256245
257246
258#ifdef UNUSED_FUNCTION
259247/* linear interpolation */
260static double mea8000_interp_f( double org, double dst )
248static int mea8000_interp( UINT16 org, UINT16 dst )
261249{
262   return org + ((dst-org) * mea8000.framepos) / mea8000.framelength;
250   return org + (((dst-org) * mea8000.framepos) >> mea8000.framelog);
263251}
264#endif
265252
266253
267#ifndef FLOAT_MODE /* UINT16 version */
268254
269
270
271255/* apply second order digital filter, sampling at F0 */
272256static int mea8000_filter_step( int i, int input )
273257{
274258   /* frequency */
275   int fm = mea8000_interp_i(mea8000.f[i].last_fm, mea8000.f[i].fm);
259   int fm = mea8000_interp(mea8000.f[i].last_fm, mea8000.f[i].fm);
276260   /* bandwidth */
277   int bw = mea8000_interp_i(mea8000.f[i].last_bw, mea8000.f[i].bw);
261   int bw = mea8000_interp(mea8000.f[i].last_bw, mea8000.f[i].bw);
278262   /* filter coefficients */
279263   int b = (cos_table[fm] * exp_table[bw]) / QUANT;
280264   int c = exp2_table[bw];
r3147r3148
286270}
287271
288272
289
290273/* random waveform, in [-QUANT,QUANT] */
291274static int mea8000_noise_gen( void )
292275{
r3147r3148
299282/* sawtooth waveform at F0, in [-QUANT,QUANT] */
300283static int mea8000_freq_gen( void )
301284{
302   int pitch = mea8000_interp_i(mea8000.last_pitch, mea8000.pitch);
285   int pitch = mea8000_interp(mea8000.last_pitch, mea8000.pitch);
303286   mea8000.phi = (mea8000.phi + pitch) % F0;
304287   return ((mea8000.phi % F0) * QUANT * 2) / F0 - QUANT;
305288}
r3147r3148
310293static int mea8000_compute_sample( void )
311294{
312295   int i;
313   int in, out;
314   int ampl = mea8000_interp_i(mea8000.last_ampl, mea8000.ampl);
296   int out;
297   int ampl = mea8000_interp(mea8000.last_ampl, mea8000.ampl);
315298
316299   if (mea8000.noise)
317      in = mea8000_noise_gen();
300      out = mea8000_noise_gen();
318301   else
319      in = mea8000_freq_gen();
320   in = (in * ampl) / 1024;
302      out = mea8000_freq_gen();
321303
304   out *= ampl / 32;
305
322306   for (i=0; i<4; i++)
323      in = mea8000_filter_step(i, in);
324   out = in;
307   {
308      out = mea8000_filter_step(i, out);
309   }
310
311   if ( out > 32767 )
312      out = 32767;
313   if ( out < -32767)
314      out = -32767;
325315   return out;
326316}
327317
r3147r3148
331321
332322
333323
324/* linear interpolation */
325static double mea8000_interp( double org, double dst )
326{
327   return org + ((dst-org) * mea8000.framepos) / mea8000.framelength;
328}
329
330
331
332/* apply second order digital filter, sampling at F0 */
334333static double mea8000_filter_step( int i, double input )
335334{
336   double fm = mea8000_interp_f(mea8000.f[i].last_fm, mea8000.f[i].fm);
337   double bw = mea8000_interp_f(mea8000.f[i].last_bw, mea8000.f[i].bw);
335   double fm = mea8000_interp(mea8000.f[i].last_fm, mea8000.f[i].fm);
336   double bw = mea8000_interp(mea8000.f[i].last_bw, mea8000.f[i].bw);
338337   double b = 2.*cos(2.*M_PI*fm/F0);
339338   double c = -exp(-M_PI*bw/F0);
340339   double next_output =
r3147r3148
359358/* sawtooth waveform at F0, in [-1,1] */
360359static double mea8000_freq_gen( void )
361360{
362   int pitch = mea8000_interp_i(mea8000.last_pitch, mea8000.pitch);
361   int pitch = mea8000_interp(mea8000.last_pitch, mea8000.pitch);
363362   mea8000.phi += pitch;
364363   return (double) (mea8000.phi % F0) / (F0/2.) - 1.;
365364}
366365
367366
368
367/* sample in [-32767,32767], at F0 */
369368static int mea8000_compute_sample( void )
370369{
371370   int i;
372   double in, out;
373   double ampl = mea8000_interp_f(mea8000.last_ampl, mea8000.ampl);
371   double out;
372   double ampl = mea8000_interp(8.*mea8000.last_ampl, 8.*mea8000.ampl);
374373
375374   if (mea8000.noise)
376      in = mea8000_noise_gen();
375      out = mea8000_noise_gen();
377376   else
378      in = mea8000_freq_gen();
379   in *= ampl / 1000.;
377      out = mea8000_freq_gen();
380378
379   out *= ampl;
380
381381   for (i=0; i<4; i++)
382382   {
383      in = mea8000_filter_step(i, in);
384      out += in;
383      out = mea8000_filter_step(i, out);
385384   }
385
386   if ( out > 32767 )
387      out = 32767;
388   if ( out < -32767)
389      out = -32767;
386390   return out;
387391}
388392
389393
390
391394#endif
392395
393396
r3147r3148
462465   /* enter stop mode */
463466   timer_reset( mea8000.timer, attotime_never );
464467   mea8000.state = MEA8000_STOPPED;
465   dac_signed_data_16_w(mea8000.channel, 0);
468   dac_signed_data_16_w(mea8000.channel, 0x8000);
466469}
467470
468471
r3147r3148
477480      /* sample is really computed only every 8-th time */
478481      mea8000.lastsample = mea8000.sample;
479482      mea8000.sample = mea8000_compute_sample();
480      dac_signed_data_16_w(mea8000.channel, mea8000.lastsample);
483      dac_signed_data_16_w(mea8000.channel, 0x8000+mea8000.lastsample);
481484   }
482485   else
483486   {
r3147r3148
485488      int sample =
486489         mea8000.lastsample +
487490         ((pos*(mea8000.sample-mea8000.lastsample)) / SUPERSAMPLING);
488      dac_signed_data_16_w(mea8000.channel, sample);
491      dac_signed_data_16_w(mea8000.channel, 0x8000+sample);
489492   }
490493
491494   mea8000.framepos++;
492   if (mea8000.framepos == mea8000.framelength)
495   if (mea8000.framepos >= mea8000.framelength)
493496   {
494497      mea8000_shift_frame();
495498      /* end of frame */

Previous 15994 Revisions Next


© 1998-2018 The MESS Team