fluid_aufile.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:4k
源码类别:

midi

开发平台:

C/C++

  1. /* FluidSynth - A Software Synthesizer
  2.  *
  3.  * Copyright (C) 2003  Peter Hanappe and others.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public License
  7.  * as published by the Free Software Foundation; either version 2 of
  8.  * the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18.  * 02111-1307, USA
  19.  */
  20. /* fluid_aufile.c
  21.  *
  22.  * Audio driver, outputs the audio to a file (non real-time)
  23.  *
  24.  */
  25. #include "fluid_adriver.h"
  26. #include "fluid_settings.h"
  27. #include "fluid_sys.h"
  28. #include "config.h"
  29. #include <stdio.h>
  30. /** fluid_file_audio_driver_t
  31.  *
  32.  * This structure should not be accessed directly. Use audio port
  33.  * functions instead.
  34.  */
  35. typedef struct {
  36. fluid_audio_driver_t driver;
  37. fluid_audio_func_t callback;
  38. void* data;
  39. fluid_file_renderer_t* renderer;
  40. int period_size;
  41. double sample_rate;
  42. fluid_timer_t* timer;
  43. unsigned int samples;
  44. } fluid_file_audio_driver_t;
  45. fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings,
  46.   fluid_synth_t* synth);
  47. int delete_fluid_file_audio_driver(fluid_audio_driver_t* p);
  48. static int fluid_file_audio_run_s16(void* d, unsigned int msec);
  49. /**************************************************************
  50.  *
  51.  *        'file' audio driver
  52.  * 
  53.  */
  54. fluid_audio_driver_t*
  55. new_fluid_file_audio_driver(fluid_settings_t* settings,
  56.     fluid_synth_t* synth)
  57. {
  58. fluid_file_audio_driver_t* dev;
  59. int msec;
  60. dev = FLUID_NEW(fluid_file_audio_driver_t);
  61. if (dev == NULL) {
  62. FLUID_LOG(FLUID_ERR, "Out of memory");
  63. return NULL;
  64. }
  65. FLUID_MEMSET(dev, 0, sizeof(fluid_file_audio_driver_t));
  66. fluid_settings_getint(settings, "audio.period-size", &dev->period_size);
  67. fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate);
  68. dev->data = synth;
  69. dev->callback = (fluid_audio_func_t) fluid_synth_process;
  70. dev->samples = 0;
  71. dev->renderer = new_fluid_file_renderer(synth);
  72. if (dev->renderer == NULL)
  73. goto error_recovery;
  74. msec = (int) (0.5 + dev->period_size / dev->sample_rate * 1000.0);
  75. dev->timer = new_fluid_timer(msec, fluid_file_audio_run_s16, (void*) dev, TRUE, FALSE, TRUE);
  76. if (dev->timer == NULL) {
  77. FLUID_LOG(FLUID_PANIC, "Couldn't create the audio thread.");
  78. goto error_recovery;
  79. }
  80. return (fluid_audio_driver_t*) dev;
  81.  error_recovery:
  82. delete_fluid_file_audio_driver((fluid_audio_driver_t*) dev);
  83. return NULL;
  84. }
  85. int delete_fluid_file_audio_driver(fluid_audio_driver_t* p)
  86. {
  87. fluid_file_audio_driver_t* dev = (fluid_file_audio_driver_t*) p;
  88. if (dev == NULL) {
  89. return FLUID_OK;
  90. }
  91. if (dev->timer != NULL) {
  92. delete_fluid_timer(dev->timer);
  93. }
  94. if (dev->renderer != NULL) {
  95. delete_fluid_file_renderer(dev->renderer);
  96. }
  97. FLUID_FREE(dev);
  98. return FLUID_OK;
  99. }
  100. static int fluid_file_audio_run_s16(void* d, unsigned int clock_time)
  101. {
  102. fluid_file_audio_driver_t* dev = (fluid_file_audio_driver_t*) d;
  103. unsigned int sample_time;
  104. sample_time = (unsigned int) (dev->samples / dev->sample_rate * 1000.0);
  105. if (sample_time > clock_time) {
  106. return 1;
  107. }
  108. dev->samples += dev->period_size;
  109. return fluid_file_renderer_process_block(dev->renderer) == FLUID_OK ? 1 : 0;
  110. }