Simple Python struct issue

Discussion in 'Python' started by Carlo DiCelico, Oct 2, 2009.

  1. I saw an article on O'Reilly about using NumPy and Dislin to analyze
    and visualize WAV files. It's a really fantastic article but was a
    little out of date. I updated the script to work with the newer
    modules &etc but am still having trouble getting it working.

    The line

    temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    128.0

    always returns the same error: "Traceback (most recent call last):
    File "pysono.py", line 31, in <module>
    temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    128.0
    struct.error: unpack requires a string argument of length 256" when I
    do python pysono.py test.wav 256

    I'm sure it's probably something simple but I just can't see what it
    is!

    Here's the original code: http://onlamp.com/python/2001/01/31/graphics/pysono.py

    Thanks!
     
    Carlo DiCelico, Oct 2, 2009
    #1
    1. Advertising

  2. Carlo DiCelico

    Simon Forman Guest

    On Fri, Oct 2, 2009 at 12:07 PM, Carlo DiCelico
    <> wrote:
    > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    > and visualize WAV files. It's a really fantastic article but was a
    > little out of date. I updated the script to work with the newer
    > modules &etc but am still having trouble getting it working.
    >
    > The line
    >
    > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    > 128.0
    >
    > always returns the same error: "Traceback (most recent call last):
    >  File "pysono.py", line 31, in <module>
    >   temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    > 128.0
    > struct.error: unpack requires a string argument of length 256" when I
    > do python pysono.py test.wav 256
    >
    > I'm sure it's probably something simple but I just can't see what it
    > is!
    >
    > Here's the original code: http://onlamp.com/python/2001/01/31/graphics/pysono.py
    >
    > Thanks!


    In:

    struct.unpack("%dB" % (fft_length), tempb)

    tempb is not length 256.

    Also, note that (foo) is the same as just foo. To create a tuple of
    length 1 you must say (foo,)

    HTH,
    ~Simon
     
    Simon Forman, Oct 2, 2009
    #2
    1. Advertising

  3. On Oct 2, 12:15 pm, Simon Forman <> wrote:
    > On Fri, Oct 2, 2009 at 12:07 PM, Carlo DiCelico
    >
    >
    >
    >
    >
    > <> wrote:
    > > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    > > and visualize WAV files. It's a really fantastic article but was a
    > > little out of date. I updated the script to work with the newer
    > > modules &etc but am still having trouble getting it working.

    >
    > > The line

    >
    > > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    > > 128.0

    >
    > > always returns the same error: "Traceback (most recent call last):
    > >  File "pysono.py", line 31, in <module>
    > >   temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    > > 128.0
    > > struct.error: unpack requires a string argument of length 256" when I
    > > do python pysono.py test.wav 256

    >
    > > I'm sure it's probably something simple but I just can't see what it
    > > is!

    >
    > > Here's the original code:http://onlamp.com/python/2001/01/31/graphics/pysono.py

    >
    > > Thanks!

    >
    > In:
    >
    > struct.unpack("%dB" % (fft_length), tempb)
    >
    > tempb is not length 256.
    >
    > Also, note that (foo) is the same as just foo.  To create a tuple of
    > length 1 you must say (foo,)
    >
    > HTH,
    > ~Simon


    I'm sorry, I'm not sure what you're referring to when you say "Also,
    note that (foo) is the same as just foo. To create a tuple of length
    1 you must say (foo,)". The 256 is passed into the script as an
    argument and then assigned to the variable fft_length, which you can
    see in that line. So, whatever value I pass in comes out in the error.
    What you're saying is that the error happens because tempb isn't the
    length of any of those values (i.e., 128, 256, 512, etc)? (1) How
    could I determine the length of tempb? and (2) It's doing this ->
    tempb = fp.readframes(fft_length); right before doing the struct.unpack
    (); could the splitting of the frames into frames of length fft_length
    be causing this error?

    Thanks for the help!
    Carlo
     
    Carlo DiCelico, Oct 2, 2009
    #3
  4. Carlo DiCelico

    MRAB Guest

    Carlo DiCelico wrote:
    > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    > and visualize WAV files. It's a really fantastic article but was a
    > little out of date. I updated the script to work with the newer
    > modules &etc but am still having trouble getting it working.
    >
    > The line
    >
    > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    > 128.0
    >
    > always returns the same error: "Traceback (most recent call last):
    > File "pysono.py", line 31, in <module>
    > temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    > 128.0
    > struct.error: unpack requires a string argument of length 256" when I
    > do python pysono.py test.wav 256
    >
    > I'm sure it's probably something simple but I just can't see what it
    > is!
    >
    > Here's the original code: http://onlamp.com/python/2001/01/31/graphics/pysono.py
    >

    ..readframes(n) returns (at most) n _frames_ as a bytestring (str), not n
    bytes. I tried reading 256 frames from a .wav file containing stereo at
    16 bits per channel and got 1024 bytes (4 bytes per frame, not
    surprisingly!).
     
    MRAB, Oct 2, 2009
    #4
  5. Carlo DiCelico

    Simon Forman Guest

    On Fri, Oct 2, 2009 at 12:35 PM, Carlo DiCelico
    <> wrote:
    > On Oct 2, 12:15 pm, Simon Forman <> wrote:
    >> On Fri, Oct 2, 2009 at 12:07 PM, Carlo DiCelico
    >> <> wrote:
    >> > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    >> > and visualize WAV files. It's a really fantastic article but was a
    >> > little out of date. I updated the script to work with the newer
    >> > modules &etc but am still having trouble getting it working.

    >>
    >> > The line

    >>
    >> > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    >> > 128.0

    >>
    >> > always returns the same error: "Traceback (most recent call last):
    >> >  File "pysono.py", line 31, in <module>
    >> >   temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    >> > 128.0
    >> > struct.error: unpack requires a string argument of length 256" when I
    >> > do python pysono.py test.wav 256

    >>
    >> > I'm sure it's probably something simple but I just can't see what it
    >> > is!

    >>
    >> > Here's the original code:http://onlamp.com/python/2001/01/31/graphics/pysono.py

    >>
    >> > Thanks!

    >>
    >> In:
    >>
    >> struct.unpack("%dB" % (fft_length), tempb)
    >>
    >> tempb is not length 256.
    >>
    >> Also, note that (foo) is the same as just foo.  To create a tuple of
    >> length 1 you must say (foo,)
    >>
    >> HTH,
    >> ~Simon

    >
    > I'm sorry, I'm not sure what you're referring to when you say "Also,
    > note that (foo) is the same as just foo.  To create a tuple of length
    > 1 you must say (foo,)".


    Sorry about that. All I mean is that in python putting parentheses
    around an expression "(some_object)" does not create a tuple unless
    you also use a comma ","

    I hope the following examples show what I mean:

    In [1]: (2)
    Out[1]: 2

    In [2]: (2,)
    Out[2]: (2,)

    In [3]: 2,
    Out[3]: (2,)

    In [4]: n = 2,

    In [5]: "%s" % (n,)
    Out[5]: '(2,)'

    In [6]: "%s" % (n)
    Out[6]: '2'

    In [7]: "%s" % n
    Out[7]: '2'


    Your code:

    "%dB" % (fft_length)

    is the same as

    "%dB" % fft_length

    But what you probably meant was

    "%dB" % (fft_length,)

    Note the comma. People do this to prevent string formatting errors if
    fft_length should ever happen to be a tuple rather than an int (or
    whatever.)


    > The 256 is passed into the script as an
    > argument and then assigned to the variable fft_length, which you can
    > see in that line. So, whatever value I pass in comes out in the error.
    > What you're saying is that the error happens because tempb isn't the
    > length of any of those values (i.e., 128, 256, 512, etc)?


    Yes, whatever tempb is, it isn't "a string argument of length 256" as
    the traceback says.

    > (1) How
    > could I determine the length of tempb?


    If it's a string, len(tempb) will return it's length.

    > and (2) It's doing this ->
    > tempb = fp.readframes(fft_length); right before doing the struct.unpack
    > (); could the splitting of the frames into frames of length fft_length
    > be causing this error?


    See MRAB's reply. :]

    > Thanks for the help!


    You're very welcome.

    One other thing, in the code you posted it has "Float", but in the
    traceback it has "float". Generally speaking when you post code to a
    newsgroup for help you should paste in the exact code, rather than
    retyping it manually.

    Warm regards, and happy hacking!
     
    Simon Forman, Oct 2, 2009
    #5
  6. On Oct 2, 3:17 pm, Simon Forman <> wrote:
    > On Fri, Oct 2, 2009 at 12:35 PM, Carlo DiCelico
    >
    >
    >
    >
    >
    > <> wrote:
    > > On Oct 2, 12:15 pm, Simon Forman <> wrote:
    > >> On Fri, Oct 2, 2009 at 12:07 PM, Carlo DiCelico
    > >> <> wrote:
    > >> > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    > >> > and visualize WAV files. It's a really fantastic article but was a
    > >> > little out of date. I updated the script to work with the newer
    > >> > modules &etc but am still having trouble getting it working.

    >
    > >> > The line

    >
    > >> > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    > >> > 128.0

    >
    > >> > always returns the same error: "Traceback (most recent call last):
    > >> >  File "pysono.py", line 31, in <module>
    > >> >   temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    > >> > 128.0
    > >> > struct.error: unpack requires a string argument of length 256" when I
    > >> > do python pysono.py test.wav 256

    >
    > >> > I'm sure it's probably something simple but I just can't see what it
    > >> > is!

    >
    > >> > Here's the original code:http://onlamp.com/python/2001/01/31/graphics/pysono.py

    >
    > >> > Thanks!

    >
    > >> In:

    >
    > >> struct.unpack("%dB" % (fft_length), tempb)

    >
    > >> tempb is not length 256.

    >
    > >> Also, note that (foo) is the same as just foo.  To create a tuple of
    > >> length 1 you must say (foo,)

    >
    > >> HTH,
    > >> ~Simon

    >
    > > I'm sorry, I'm not sure what you're referring to when you say "Also,
    > > note that (foo) is the same as just foo.  To create a tuple of length
    > > 1 you must say (foo,)".

    >
    > Sorry about that.  All I mean is that in python putting parentheses
    > around an expression "(some_object)" does not create a tuple unless
    > you also use a comma ","
    >
    > I hope the following examples show what I mean:
    >
    > In [1]: (2)
    > Out[1]: 2
    >
    > In [2]: (2,)
    > Out[2]: (2,)
    >
    > In [3]: 2,
    > Out[3]: (2,)
    >
    > In [4]: n = 2,
    >
    > In [5]: "%s" % (n,)
    > Out[5]: '(2,)'
    >
    > In [6]: "%s" % (n)
    > Out[6]: '2'
    >
    > In [7]: "%s" % n
    > Out[7]: '2'
    >
    > Your code:
    >
    > "%dB" % (fft_length)
    >
    > is the same as
    >
    > "%dB" % fft_length
    >
    > But what you probably meant was
    >
    > "%dB" % (fft_length,)
    >
    > Note the comma.  People do this to prevent string formatting errors if
    > fft_length should ever happen to be a tuple rather than an int (or
    > whatever.)
    >
    > > The 256 is passed into the script as an
    > > argument and then assigned to the variable fft_length, which you can
    > > see in that line. So, whatever value I pass in comes out in the error.
    > > What you're saying is that the error happens because tempb isn't the
    > > length of any of those values (i.e., 128, 256, 512, etc)?

    >
    > Yes, whatever tempb is, it isn't "a string argument of length 256" as
    > the traceback says.
    >
    > > (1) How
    > > could I determine the length of tempb?

    >
    > If it's a string, len(tempb) will return it's length.
    >
    > > and (2) It's doing this ->
    > > tempb = fp.readframes(fft_length); right before doing the struct.unpack
    > > (); could the splitting of the frames into frames of length fft_length
    > > be causing this error?

    >
    > See MRAB's reply. :]
    >
    > > Thanks for the help!

    >
    > You're very welcome.
    >
    > One other thing, in the code you posted it has "Float", but in the
    > traceback it has "float".  Generally speaking when you post code to a
    > newsgroup for help you should paste in the exact code, rather than
    > retyping it manually.
    >
    > Warm regards, and happy hacking!


    Ah, yes, makes so much more sense now. Thanks very much for the help!
    The discrepancy between Float and float has to do with the fact that
    in the code I linked to, he's using an old version of numpy. In my
    code, I'm using the new version of numpy, which uses float instead of
    Float. Sorry about that, thanks again.
     
    Carlo DiCelico, Oct 2, 2009
    #6
  7. On Oct 2, 12:49 pm, MRAB <> wrote:
    > Carlo DiCelico wrote:
    > > I saw an article on O'Reilly about using NumPy and Dislin to analyze
    > > and visualize WAV files. It's a really fantastic article but was a
    > > little out of date. I updated the script to work with the newer
    > > modules &etc but am still having trouble getting it working.

    >
    > > The line

    >
    > > temp[i,:] = array(struct.unpack("%dB"%(fft_length), tempb),Float) -
    > > 128.0

    >
    > > always returns the same error: "Traceback (most recent call last):
    > >   File "pysono.py", line 31, in <module>
    > >    temp[i,:] = array(struct.unpack("%dB"%(fft_length),tempb),float) -
    > > 128.0
    > > struct.error: unpack requires a string argument of length 256" when I
    > > do python pysono.py test.wav 256

    >
    > > I'm sure it's probably something simple but I just can't see what it
    > > is!

    >
    > > Here's the original code:http://onlamp.com/python/2001/01/31/graphics/pysono.py

    >
    > .readframes(n) returns (at most) n _frames_ as a bytestring (str), not n
    > bytes. I tried reading 256 frames from a .wav file containing stereo at
    > 16 bits per channel and got 1024 bytes (4 bytes per frame, not
    > surprisingly!).


    Yes! Thank you very much for pointing this out, don't know how I
    missed it!
     
    Carlo DiCelico, Oct 2, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. RA Scheltema
    Replies:
    3
    Views:
    410
    RA Scheltema
    Jan 6, 2004
  2. Gunnar G

    struct in struct

    Gunnar G, May 31, 2004, in forum: C++
    Replies:
    14
    Views:
    815
  3. DanielEKFA
    Replies:
    8
    Views:
    626
    DanielEKFA
    May 16, 2005
  4. James Harris
    Replies:
    4
    Views:
    1,431
    James Harris
    Oct 9, 2003
  5. Chris Fogelklou
    Replies:
    36
    Views:
    1,410
    Chris Fogelklou
    Apr 20, 2004
Loading...

Share This Page