tool to upload data to a SuperCharger cartridge
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
7.3KB

  1. /**
  2. this file is based upon:
  3. @file patest_sine8.c
  4. @ingroup test_src
  5. @brief Test 8 bit data: play a sine wave for several seconds.
  6. @author Ross Bencina <rossb@audiomulch.com>
  7. */
  8. /*
  9. * $Id: patest_sine8.c 1748 2011-09-01 22:08:32Z philburk $
  10. *
  11. * This program uses the PortAudio Portable Audio Library.
  12. * For more information see: http://www.portaudio.com
  13. * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
  14. *
  15. * Permission is hereby granted, free of charge, to any person obtaining
  16. * a copy of this software and associated documentation files
  17. * (the "Software"), to deal in the Software without restriction,
  18. * including without limitation the rights to use, copy, modify, merge,
  19. * publish, distribute, sublicense, and/or sell copies of the Software,
  20. * and to permit persons to whom the Software is furnished to do so,
  21. * subject to the following conditions:
  22. *
  23. * The above copyright notice and this permission notice shall be
  24. * included in all copies or substantial portions of the Software.
  25. *
  26. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  27. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  28. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  29. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  30. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  31. * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  32. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  33. */
  34. /*
  35. * The text above constitutes the entire PortAudio license; however,
  36. * the PortAudio community also makes the following non-binding requests:
  37. *
  38. * Any person wishing to distribute modifications to the Software is
  39. * requested to send the modifications to the original developer so that
  40. * they can be incorporated into the canonical version. It is also
  41. * requested that these non-binding requests be included along with the
  42. * license above.
  43. */
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <math.h>
  47. #include <portaudio.h>
  48. #include "paplay.h"
  49. #define SAMPLE_RATE (44100)
  50. #define TEST_UNSIGNED (0)
  51. #if TEST_UNSIGNED
  52. #define TEST_FORMAT paUInt8
  53. typedef unsigned char sample_t;
  54. #define SILENCE ((sample_t)0x80)
  55. #else
  56. #define TEST_FORMAT paInt8
  57. typedef char sample_t;
  58. #define SILENCE ((sample_t)0x00)
  59. #endif
  60. struct playdata_s
  61. {
  62. const unsigned char *bufferstart;
  63. int size;
  64. int played;
  65. };
  66. int palist()
  67. {
  68. PaError err;
  69. int i;
  70. int numDevices;
  71. const PaDeviceInfo *deviceInfo;
  72. err = Pa_Initialize();
  73. if( err != paNoError )
  74. {
  75. goto error;
  76. }
  77. numDevices = Pa_GetDeviceCount();
  78. if( numDevices < 0 )
  79. {
  80. fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
  81. err = numDevices;
  82. goto error;
  83. }
  84. for( i = 0; i < numDevices; i++ )
  85. {
  86. deviceInfo = Pa_GetDeviceInfo( i );
  87. fprintf( stdout, "device #%d: %s\n", i, deviceInfo->name );
  88. }
  89. Pa_Terminate();
  90. return err;
  91. error:
  92. Pa_Terminate();
  93. fprintf( stderr, "An error occured while using the portaudio stream\n" );
  94. fprintf( stderr, "Error number: %d\n", err );
  95. fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
  96. return err;
  97. }
  98. /* This routine will be called by the PortAudio engine when audio is needed.
  99. ** It may called at interrupt level on some machines so don't do anything
  100. ** that could mess up the system like calling malloc() or free().
  101. */
  102. static int pa_mem_callback( const void *inputBuffer, void *outputBuffer,
  103. unsigned long framesPerBuffer,
  104. const PaStreamCallbackTimeInfo* timeInfo,
  105. PaStreamCallbackFlags statusFlags,
  106. void *userData )
  107. {
  108. char *out = (char*)outputBuffer;
  109. struct playdata_s *playdata = (struct playdata_s*)userData;
  110. int copysize = playdata->size - playdata->played;
  111. int finished = 0;
  112. (void) inputBuffer; /* Prevent unused variable warnings. */
  113. if( copysize > framesPerBuffer )
  114. {
  115. copysize = framesPerBuffer;
  116. }
  117. else
  118. {
  119. finished = 1;
  120. }
  121. memcpy( out, playdata->bufferstart + playdata->played, copysize );
  122. if( copysize < framesPerBuffer )
  123. {
  124. /* zero remainder of final buffer */
  125. memset( out + copysize, 0, framesPerBuffer - copysize );
  126. }
  127. playdata->played += copysize;
  128. return finished;
  129. }
  130. /*******************************************************************/
  131. int paplay( const unsigned char *data, int size, const char *devicename )
  132. {
  133. struct playdata_s playdata;
  134. PaStreamParameters outputParameters;
  135. PaStream* stream;
  136. PaError err;
  137. const PaDeviceInfo *deviceInfo;
  138. int i;
  139. int numDevices;
  140. playdata.bufferstart = data;
  141. playdata.size = size;
  142. playdata.played = 0;
  143. err = Pa_Initialize();
  144. if( err != paNoError )
  145. {
  146. goto error;
  147. }
  148. numDevices = Pa_GetDeviceCount();
  149. if( numDevices < 0 )
  150. {
  151. fprintf( stderr, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
  152. err = numDevices;
  153. goto error;
  154. }
  155. outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
  156. if( devicename )
  157. {
  158. int s = strlen( devicename );
  159. for( i=0; i<numDevices; i++ )
  160. {
  161. deviceInfo = Pa_GetDeviceInfo( i );
  162. if( devicename[s-1] == '*' )
  163. {
  164. if( !strncmp( devicename, deviceInfo->name, s - 1) )
  165. {
  166. outputParameters.device = i;
  167. }
  168. }
  169. else
  170. {
  171. if( !strcmp( devicename, deviceInfo->name ) )
  172. {
  173. outputParameters.device = i;
  174. }
  175. }
  176. }
  177. }
  178. if( outputParameters.device == paNoDevice )
  179. {
  180. fprintf(stderr,"Error: No default output device.\n");
  181. goto error;
  182. }
  183. deviceInfo = Pa_GetDeviceInfo( outputParameters.device );
  184. fprintf( stderr, "using device #%d: %s\n", outputParameters.device, deviceInfo->name );
  185. outputParameters.channelCount = 1; /* Mono output. */
  186. outputParameters.sampleFormat = TEST_FORMAT;
  187. outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
  188. outputParameters.hostApiSpecificStreamInfo = NULL;
  189. err = Pa_OpenStream( &stream,
  190. NULL, /* No input. */
  191. &outputParameters,
  192. SAMPLE_RATE,
  193. 256, /* Frames per buffer. */
  194. paClipOff, /* We won't output out of range samples so don't bother clipping them. */
  195. pa_mem_callback,
  196. &playdata );
  197. if( err != paNoError )
  198. {
  199. goto error;
  200. }
  201. err = Pa_StartStream( stream );
  202. if( err != paNoError )
  203. {
  204. goto error;
  205. }
  206. while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
  207. {
  208. Pa_Sleep(100);
  209. }
  210. if( err < 0 )
  211. {
  212. goto error;
  213. }
  214. err = Pa_CloseStream( stream );
  215. if( err != paNoError )
  216. {
  217. goto error;
  218. }
  219. Pa_Terminate();
  220. return err;
  221. error:
  222. Pa_Terminate();
  223. fprintf( stderr, "An error occured while using the portaudio stream\n" );
  224. fprintf( stderr, "Error number: %d\n", err );
  225. fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
  226. return err;
  227. }