sound.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import consts
  2. import tag
  3. import wave
  4. import stream
  5. supportedCodecs = (
  6. consts.AudioCodec.MP3,
  7. consts.AudioCodec.UncompressedNativeEndian,
  8. consts.AudioCodec.UncompressedLittleEndian,
  9. )
  10. uncompressed = (
  11. consts.AudioCodec.UncompressedNativeEndian,
  12. consts.AudioCodec.UncompressedLittleEndian,
  13. )
  14. REASON_OK = None
  15. REASON_EMPTY = 'stream is empty'
  16. def get_header(stream_or_tag):
  17. if isinstance(stream_or_tag, list):
  18. assert len(stream_or_tag) > 0, 'empty stream'
  19. return stream_or_tag[0]
  20. else:
  21. assert isinstance(stream_or_tag, tag.TagDefineSound), 'sound is not a stream or DefineSound tag'
  22. return stream_or_tag
  23. def reason_unsupported(stream_or_tag):
  24. header = get_header(stream_or_tag)
  25. is_stream = isinstance(stream_or_tag, list)
  26. if header.soundFormat not in supportedCodecs:
  27. return 'codec %s (%d) not supported' % (consts.AudioCodec.tostring(header.soundFormat),
  28. header.soundFormat)
  29. if is_stream and len(stream_or_tag) == 1:
  30. return REASON_EMPTY
  31. return REASON_OK
  32. def supported(stream_or_tag):
  33. return reason_unsupported(stream_or_tag) is None
  34. def junk(stream_or_tag):
  35. return reason_unsupported(stream_or_tag) == REASON_EMPTY
  36. def get_wave_for_header(header, output):
  37. w = wave.open(output, 'w')
  38. w.setframerate(consts.AudioSampleRate.Rates[header.soundRate])
  39. w.setnchannels(consts.AudioChannels.Channels[header.soundChannels])
  40. w.setsampwidth(consts.AudioSampleSize.Bits[header.soundSampleSize] / 8)
  41. return w
  42. def write_stream_to_file(stream, output):
  43. header = get_header(stream)
  44. w = None
  45. if header.soundFormat in uncompressed:
  46. w = get_wave_for_header(header, output)
  47. for block in stream[1:]:
  48. block.complete_parse_with_header(header)
  49. if header.soundFormat == consts.AudioCodec.MP3:
  50. output.write(block.mpegFrames)
  51. else:
  52. w.writeframes(block.data.read())
  53. if w:
  54. w.close()
  55. def write_sound_to_file(st, output):
  56. assert isinstance(st, tag.TagDefineSound)
  57. if st.soundFormat == consts.AudioCodec.MP3:
  58. swfs = stream.SWFStream(st.soundData)
  59. seekSamples = swfs.readSI16()
  60. output.write(swfs.read())
  61. elif st.soundFormat in uncompressed:
  62. w = get_wave_for_header(st, output)
  63. w.writeframes(st.soundData.read())
  64. w.close()