libasap.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * libasap.c - ASAP plugin for XMMS
  3.  *
  4.  * Copyright (C) 2006  Piotr Fusik
  5.  *
  6.  * This file is part of ASAP (Another Slight Atari Player),
  7.  * see http://asap.sourceforge.net
  8.  *
  9.  * ASAP is free software; you can redistribute it and/or modify it
  10.  * under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 2 of the License,
  12.  * or (at your option) any later version.
  13.  *
  14.  * ASAP is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty
  16.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17.  * See the GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with ASAP; if not, write to the Free Software Foundation, Inc.,
  21.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  22.  */
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <pthread.h>
  26. #include <xmms/plugin.h>
  27. #include <xmms/util.h>
  28. #include "asap.h"
  29. #define FREQUENCY        44100
  30. #define BITS_PER_SAMPLE    16
  31. #define QUALITY            1
  32. #define BUFFERED_BLOCKS    512
  33. static unsigned int channels;
  34. static unsigned int buffered_bytes;
  35. static InputPlugin mod;
  36. static pthread_t thread_handle;
  37. static volatile int thread_run = FALSE;
  38. static void init(void)
  39. {
  40. ASAP_Initialize(FREQUENCY,
  41. BITS_PER_SAMPLE == 8 ? AUDIO_FORMAT_U8 : AUDIO_FORMAT_S16_NE, QUALITY);
  42. }
  43. #define EXT(c1, c2, c3) ((c1 + (c2 << 8) + (c3 << 16)) | 0x202020)
  44. static int is_our_file(char *filename)
  45. {
  46. const char *p;
  47. int ext;
  48. for (p = filename; *p != ''; p++);
  49. ext = 0;
  50. for (;;) {
  51. if (--p <= filename || *p < ' ')
  52. return FALSE; /* no filename extension or invalid character */
  53. if (*p == '.')
  54. break;
  55. ext = (ext << 8) + (*p & 0xff);
  56. }
  57. switch (ext | 0x202020) {
  58. case EXT('C', 'M', 'C'):
  59. case EXT('C', 'M', 'R'):
  60. case EXT('D', 'M', 'C'):
  61. case EXT('M', 'P', 'D'):
  62. case EXT('M', 'P', 'T'):
  63. case EXT('R', 'M', 'T'):
  64. case EXT('S', 'A', 'P'):
  65. case EXT('T', 'M', 'C'):
  66. #ifdef STEREO_SOUND
  67. case EXT('T', 'M', '8'):
  68. #endif
  69. case EXT('T', 'M', '2'):
  70. return TRUE;
  71. default:
  72. return FALSE;
  73. }
  74. }
  75. static void *play_thread(void *arg)
  76. {
  77. for (;;) {
  78. static
  79. #if BITS_PER_SAMPLE == 8
  80. unsigned char
  81. #else
  82. short int
  83. #endif
  84. buffer[BUFFERED_BLOCKS * 2];
  85. ASAP_Generate(buffer, buffered_bytes);
  86. mod.add_vis_pcm(mod.output->written_time(),
  87. BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_NE,
  88. channels, buffered_bytes, buffer);
  89. while (thread_run && mod.output->buffer_free() < buffered_bytes)
  90. xmms_usleep(20000);
  91. if (!thread_run)
  92. break;
  93. mod.output->write_audio(buffer, buffered_bytes);
  94. }
  95. mod.output->buffer_free();
  96. mod.output->buffer_free();
  97. pthread_exit(NULL);
  98. }
  99. static void play_file(char *filename)
  100. {
  101. FILE *fp;
  102. static unsigned char module[65000];
  103. unsigned int module_len;
  104. fp = fopen(filename, "rb");
  105. if (fp == NULL)
  106. return;
  107. module_len = fread(module, 1, sizeof(module), fp);
  108. fclose(fp);
  109. if (!ASAP_Load(filename, module, module_len))
  110. return;
  111. ASAP_PlaySong(ASAP_GetDefSong());
  112. channels = ASAP_GetChannels();
  113. buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8);
  114. if (!mod.output->open_audio(BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_NE,
  115. FREQUENCY, channels))
  116. return;
  117. mod.set_info(NULL, -1, BITS_PER_SAMPLE * 1000, FREQUENCY, channels);
  118. thread_run = TRUE;
  119. pthread_create(&thread_handle, NULL, play_thread, NULL);
  120. }
  121. static void pause(short paused)
  122. {
  123. mod.output->pause(paused);
  124. }
  125. static void stop(void)
  126. {
  127. if (thread_run) {
  128. thread_run = FALSE;
  129. pthread_join(thread_handle, NULL);
  130. mod.output->close_audio();
  131. }
  132. }
  133. static int get_time(void)
  134. {
  135. if (!thread_run || !mod.output->buffer_playing())
  136. return -1;
  137. return mod.output->output_time();
  138. }
  139. static InputPlugin mod = {
  140. NULL, NULL,
  141. "ASAP " ASAP_VERSION,
  142. init,
  143. NULL,
  144. NULL,
  145. is_our_file,
  146. NULL,
  147. play_file,
  148. stop,
  149. pause,
  150. NULL,
  151. NULL,
  152. get_time,
  153. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  154. };
  155. InputPlugin *get_iplugin_info(void)
  156. {
  157. return &mod;
  158. }