instead of depending on data = array('h') .. write samples 1 by 1 to w = wave.open("wav.wav", "w")

'2+ electriclightheads at gmail.com
Wed Jul 29 20:26:47 CEST 2009


o wow .. there's still a lot to learn ..
okay .. if i get stucked with the memory usage issue
will try this hybrid .. thanx for the example!!

it took about 40 min to render 1min of wav
so i'll just keep this project like 15 sec oriented
and maybe that'll keep me away from the mem trouble

and my oil.py is still so cheap..
sad thing is that "the result sound strange" is true to
all versions :s

thanx again anyway!


On Wed, Jul 29, 2009 at 5:21 PM, Peter Otten<__peter__ at web.de> wrote:
> '2+ wrote:
>
>> it says
>> Wave_write.writeframes(data)
>> will that mean
>> "from array import array"
>> is a must?
>>
>> this does the job:
>>
>> import oil
>> import wave
>> from array import array
>>
>> a = oil.Sa()
>>
>> w = wave.open("current.wav", "w")
>> w.setnchannels(2)
>> w.setsampwidth(2)
>> w.setframerate(44100)
>>
>> data = array('h')
>>
>> for gas in range(44100 * 5):
>>     a.breath()
>>     r = int(32767 * (a.pulse(1) + a.pulse(2) + a.pulse(3)) / 3.0)
>>     l = int(32767 * (a.pulse(4) + a.pulse(5) + a.pulse(6)) / 3.0)
>>     data.append(r)
>>     data.append(l)
>>
>> w.writeframes(data.tostring())
>> w.close()
>>
>> don't like array becoming so huge so tested this and it was also okay:
>>
>> for gas in range(44100 * 5):
>>     a.breath()
>>     data = array('h')
>>     r = int(32767 * (a.pulse(1) + a.pulse(2) + a.pulse(3)) / 3.0)
>>     l = int(32767 * (a.pulse(4) + a.pulse(5) + a.pulse(6)) / 3.0)
>>     data.append(r)
>>     data.append(l)
>>     w.writeframes(data.tostring())
>>
>> but without array .. it becomes 15secs(3 times longer than was
>> intended to be) of wav file:
>>
>> for gas in range(44100 * 5):
>>     a.breath()
>>     r = int(32767 * (a.pulse(1) + a.pulse(2) + a.pulse(3)) / 3.0)
>>     l = int(32767 * (a.pulse(4) + a.pulse(5) + a.pulse(6)) / 3.0)
>>     w.writeframes(hex(r))
>>     w.writeframes(hex(l))
>
> Doesn't it sound strange, too? You are writing bogus bytes to the file.
> Compare:
>
>>>> import array
>>>> array.array("h", [42]).tostring()
> '*\x00'
>>>> hex(42)
> '0x2a'
>
> Not only do they differ in length, the contents are different, too. If
> you're unfamiliar with string escape codes, here's a way to see the bytes:
>
>>>> map(ord, array.array("h", [42]).tostring())
> [42, 0]
>>>> map(ord, hex(42))
> [48, 120, 50, 97]
>
>> should i just be happy with depennding on using array?
>> or is there a solution to make the last one work properly?
>
> There is a way to make the last one work: use struct.pack("h", r) instead of
> hex(r). I'm of course assuming that the first version does give you the
> desired result. You should not continue before you have verified that.
>
> I still recommend array for performance reasons. If memory usage is an issue
> you can adopt a hybrid approach:
>
> # untested
> from itertools import islice
> from array import array
>
> def gen_data():
>    for gas in xrange(44100 * 5): # range --> xrange
>        a.breath()
>        r = int(32767 * (a.pulse(1) + a.pulse(2) + a.pulse(3)) / 3.0)
>        l = int(32767 * (a.pulse(4) + a.pulse(5) + a.pulse(6)) / 3.0)
>        yield r
>        yield l
>
> data = gen_data()
> N = 2**20
> while True:
>    chunk = array('h')
>    chunk.extend(islice(data, N))
>    if not chunk:
>        break
>    w.writeframes(chunk.tostring())
>
> This will limit the array size to 4N bytes.
>
> Peter
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
SaRiGaMa's Oil Vending Orchestra
is podcasting:
http://sarigama.namaste.jp/podcast/rss.xml
and supplying oil.py for free:
http://oilpy.blogspot.com/



More information about the Python-list mailing list