Author alex_python_org
Recipients alex_python_org, gpolo
Date 2009-01-12.17:18:44
SpamBayes Score 6.08161e-05
Marked as misclassified No
Message-id <1231780728.69.0.979790939194.issue4913@psf.upfronthosting.co.za>
In-reply-to
Content
"8 bit samples stored as unsigned bytes"?
8 bit samples are 0..255 in the file. But to work with them, you'll want
them -128..127. The code assumes DC==0 sample values for simplicity.

"if len(wavs) not in [ 1, 2, 4 ]" ?
That way if you're working with mono, you can simply pass your samples
down to writesamples() without having to remember to "[ samples ]" them.
If you forget, no big deal. It's too bad that readsamples() can't know
that you want only mono samples. That would make mono work simpler.
Anyway, I don't argue very strongly for this spiff. In some ways it's
worse to be there. After all, the caller may be writing 1 frame at a
time, though I don't think that such logic would work. And would be
pretty slow, too, probably.

"Calling setnchannels"?
Since the number of channels *must* be the number of sample arrays
passed to writesamples(), either writesamples() must rely on the caller
already having gratuitously set the number of channels (correctly), or
writesamples() can simply force the issue. If the caller set the number
of channels wrongly, then the output file will be corrupt or
writesamples() would need to raise an exception. Both just make work for
the caller. get/set_nchannels() are not particularly useful if you are
using the read/write_sample API. If there were no ..frame() API,
getnchannels() might still be handy to use to find out how many channels
a wave file being read has before any samples have been read. But that's
about it.

"integers, is that the best format"?
Far bettern than the byte stream form which is useless, confusing, error
prone, and exposes the internal wave file format to the caller who could
generally care less how a wave file stores the samples. But, you bring
up a very good point, I think. I forgot to int(s) the samples when they
are put in to the arrays. The reason for an int() call on all the
samples is so that the caller can deal with samples as floats. (Which is
how he will want to deal with them if he's doing anything interesting.)
So, this:
            ws  = array.array('l', [ int(s)       for s in wav ])
            ws  = array.array('h', [ int(s)       for s in wav ])
            ws  = array.array('B', [ int(s + 128) for s in wav ])
And, for testing, in normalize_samples():
        samps   = [ s * mxm for s in samps ]
So normalize_samples() always sends floats to writesamples().


"The code layout"?
:) Well. Whatever. I know that the "official" python thing is to push
colons left. I don't like that. I've experimented in the last few years
with doing a lot of vertical alignment. Over time, I've found that it is
a great way to do things. It's pretty amazing how much easier it is to
scan and read code that has, as a start, the "="'s vertically aligned.
And, over the last few years, I've put more and more blank lines in.
Vertically compressed code tends to look like assembler language. I edit
with 200+ character wide screen so, since I stopped forcing everything
to fit on TTY, text mode CGA, or punch cards, I've lost a taste for
narrow code. In fact, I personally have a real hard time reading
line-broken code. That said, multi-lining "if" statements in ways that
allow delete/insert of lines, 1 for each "operator ()" expression, can
be very nice. Calls to routines with a gob of parameters, each on a
separate line, can sure be a good way to deal with a bad thing (routines
that take a lot of params are bad, that is). Etc. Anyway, I assumed that
the code would be reformatted by whomever maintains wave.py. No biggy.

"hand write the wave file for testing"?
Good point! Allows a test to do things like odd numbers of frames, 1
frame, max'ed out sample values, long runs of silence, DC offsets, etc.
Do you know whether there are already test files for wave.py? They'd
have those sorts of things in them. Hmmm. It's odd that wave.py doesn't
run from the command line and dump the header or something, at least.
Maybe do some simple conversions (8/16, mono/stereo switches, reverses
... that sort of thing). Would be handy.


This code is not tested on a big-endian machine. I ran it under XP
(py2.4) and Ubuntu64 (py2.5) and all the output files CRC the same on
both PCs.
History
Date User Action Args
2009-01-12 17:18:48alex_python_orgsetrecipients: + alex_python_org, gpolo
2009-01-12 17:18:48alex_python_orgsetmessageid: <1231780728.69.0.979790939194.issue4913@psf.upfronthosting.co.za>
2009-01-12 17:18:47alex_python_orglinkissue4913 messages
2009-01-12 17:18:44alex_python_orgcreate