audiosample.bmx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. Strict
  2. Rem
  3. bbdoc: Audio/Audio samples
  4. End Rem
  5. Module BRL.AudioSample
  6. ModuleInfo "Version: 1.04"
  7. ModuleInfo "Author: Mark Sibly"
  8. ModuleInfo "License: zlib/libpng"
  9. ModuleInfo "Copyright: Blitz Research Ltd"
  10. ModuleInfo "Modserver: BRL"
  11. ModuleInfo "History: 1.04 Release"
  12. ModuleInfo "History: ChannelsPerSample array added"
  13. Import BRL.Stream
  14. Import "sample.bmx"
  15. Rem
  16. bbdoc: Audio sample type
  17. end rem
  18. Type TAudioSample
  19. Rem
  20. bbdoc: Byte pointer to sample data
  21. end rem
  22. Field samples:Byte Ptr
  23. Rem
  24. bbdoc: Length, in samples, of the sample data
  25. end rem
  26. Field length
  27. Rem
  28. bbdoc: Sample rate
  29. end rem
  30. Field hertz
  31. Rem
  32. bbdoc: Sample format
  33. end rem
  34. Field format
  35. Field capacity
  36. Method Delete()
  37. If capacity>=0 MemFree samples
  38. End Method
  39. Rem
  40. bbdoc: Copy audio sample
  41. returns: A new audio sample object
  42. end rem
  43. Method Copy:TAudioSample()
  44. Local t:TAudioSample=Create( length,hertz,format )
  45. CopySamples samples,t.samples,format,length
  46. Return t
  47. End Method
  48. Rem
  49. bbdoc: Convert audio sample
  50. returns: A new audio sample object in the specified format
  51. end rem
  52. Method Convert:TAudioSample( to_format )
  53. Local t:TAudioSample=Create( length,hertz,to_format )
  54. ConvertSamples samples,format,t.samples,to_format,length
  55. Return t
  56. End Method
  57. Rem
  58. bbdoc: Create an audio sample
  59. returns: A new audio sample object
  60. end rem
  61. Function Create:TAudioSample( length,hertz,format )
  62. Local t:TAudioSample=New TAudioSample
  63. Local capacity=length*BytesPerSample[format]
  64. t.samples=MemAlloc( capacity )
  65. t.length=length
  66. t.hertz=hertz
  67. t.format=format
  68. t.capacity=capacity
  69. Return t
  70. End Function
  71. Rem
  72. bbdoc: Create a static audio sample
  73. returns: A new audio sample object that references an existing block of memory
  74. end rem
  75. Function CreateStatic:TAudioSample( samples:Byte Ptr,length,hertz,format )
  76. Local t:TAudioSample=New TAudioSample
  77. t.samples=samples
  78. t.length=length
  79. t.hertz=hertz
  80. t.format=format
  81. t.capacity=-1
  82. Return t
  83. End Function
  84. End Type
  85. Private
  86. Global sample_loaders:TAudioSampleLoader
  87. Public
  88. 'deprecated
  89. Function AddAudioSampleLoader( loader:TAudioSampleLoader )
  90. ' If( loader._succ ) Return
  91. ' loader._succ=sample_loaders
  92. ' sample_loaders=loader
  93. End Function
  94. Rem
  95. bbdoc: Audio sample loader type
  96. about: To create your own audio sample loaders, you should extend this type and
  97. provide a @LoadAudioSample method. To add your audio sample loader to the system,
  98. simply create an instance of it using @New.
  99. end rem
  100. Type TAudioSampleLoader
  101. Field _succ:TAudioSampleLoader
  102. Method New()
  103. _succ=sample_loaders
  104. sample_loaders=Self
  105. End Method
  106. Rem
  107. bbdoc: Load an audio sample
  108. returns: A new audio sample object, or Null if sample could not be loaded
  109. about: Extending types must implement this method.
  110. end rem
  111. Method LoadAudioSample:TAudioSample( stream:TStream ) Abstract
  112. End Type
  113. Rem
  114. bbdoc: Create an audio sample
  115. returns: An audio sample object
  116. about:
  117. @length is the number of samples to allocate for the sample. @hertz is the frequency in samples per second (hz)
  118. the audio sample will be played. @format should be one of:
  119. [ @Format | @Description
  120. * &SF_MONO8 | Mono unsigned 8 bit
  121. * &SF_MONO16LE | Mono signed 16 bit little endian
  122. * &SF_MONO16BE | Mono signed 16 bit big endian
  123. * &SF_STEREO8 | Stereo unsigned 8 bit
  124. * &SF_STEREO16LE | Stereo signed 16 bit little endian
  125. * &SF_STEREO16BE | Stereo signed 16 bit big endian
  126. ]
  127. End Rem
  128. Function CreateAudioSample:TAudioSample( length,hertz,format )
  129. Return TAudioSample.Create( length,hertz,format )
  130. End Function
  131. Rem
  132. bbdoc: Create an audio sample with existing data
  133. returns: An audio sample object that references an existing block of memory
  134. about:
  135. The memory referenced by a static audio sample is not released when the audio sample is
  136. deleted.
  137. See #CreateAudioSample for possile @format values.
  138. End Rem
  139. Function CreateStaticAudioSample:TAudioSample( samples:Byte Ptr,length,hertz,format )
  140. Return TAudioSample.CreateStatic( samples,length,hertz,format )
  141. End Function
  142. Rem
  143. bbdoc: Load an audio sample
  144. returns: An audio sample object
  145. end rem
  146. Function LoadAudioSample:TAudioSample( url:Object )
  147. Local stream:TStream=ReadStream( url )
  148. If Not stream Return
  149. Local pos=stream.Pos()
  150. If pos=-1 RuntimeError "Stream is not seekable"
  151. Local sample:TAudioSample
  152. Local loader:TAudioSampleLoader=sample_loaders
  153. While loader
  154. stream.Seek pos
  155. Try
  156. sample=loader.LoadAudioSample( stream )
  157. Catch ex:TStreamException
  158. End Try
  159. If sample Exit
  160. loader=loader._succ
  161. Wend
  162. stream.Close
  163. Return sample
  164. End Function