RE: Automatic Gain Control in Python?

2022-05-28 Thread Steve GS
You really need to understand what I am trying to do.  
It is not a simple lesson in use of podcasts.  
This is an automated system. I call it my NPR Jukebox.

15 years ago, I started with hourly URL calls to a browser to record specific 
NPR programs. It took a lot of coordination. I had to use IE because I needed 
to start and stop browsers on the hour and IE was the only one that could do 
that. Then web sites started "upgrading" to Edge. Through some trickery I was 
able to get Edge to do what IE did but it was unstable.

I then discovered the Echo Smart Speaker. I set my program to announce the 
broadcast station or podcast by speaker to the smart speaker and it cured a lot 
of headaches. I then was able to call podcasts because the Echo handles them 
through TuneIn. Unfortunately, not all broadcasts ae available as podcasts.

I am not here diddling around just playing podcasts. Let me repeat what I have 
already said. It is an automated system.  Every hour for 48 hours on every 
weekend, my system using a well-developed Excel/VBA program that vocally talks 
to the SS hourly.  The SS finds the audio and sends it to my Audacity recorder 
on another computer through aux-out to mic-in cable. The selections of audio 
are also transmitted to the community at the time of recording

That part of the system is almost flawless, well compared to that I had before. 
Although the quality, tone, and timing of the announcement, the SS still gets 
confused once in a while and goes silent for the hour. I need to detect this 
too.

Ok, now back to the original question.

Podcasts and broadcasts apparently do not use the Dolby tone to balance the 
audio levels. And I receive highly fluctuating levels of audio. Sometimes it is 
between sides of a conversation, sometimes it is the podcast vs station 
identifications, then it is great differences between one web site and another. 
 Then there's the differences with male and female voices. Imagine that you are 
watching TV late night then the commercials COME IN AT FULL BLAST.

The technology of the industry grew up with male voices and apparently sees no 
reason to adjust for female.  I have worked with audio systems and making 
recordings for more years that I want to admit.

All I want is software to detect level changes over time and attempt to 
equalize them. 
It has to be work between the SS and the recorder and is to be checking all the 
time. 

The code is to: Listen to the audio level for about 10 seconds or so and raise 
or lower the level in small increments.
It has nothing to do with understanding how to grab podcasts.  The system is 
working very well for that.


Footnote:
“What rhymes with orange?”
“No, it doesn’t..”



-Original Message-
From: Richard Damon  On Behalf Of Richard Damon
Sent: Saturday, May 28, 2022 11:37 PM
To: Steve GS 
Subject: Re: Automatic Gain Control in Python?

On 5/28/22 8:17 PM, Steve GS wrote:
> "My first thought is you are solving the wrong problem. What seems a 
> better option would be to get your code to actually connect up to the 
> podcast and just download the audio directly, rather than trying to 
> get the smart speaker to play the audio and record it with a microphone."
>
> The smart-speaker is bringing in the podcast by hourly automated 
> commands and sending by audio cable to a computer which is recording 
> it with Audacity.  This is an automated system that runs for 48 hours every 
> weekend.
> Its output is played live throughout the facility and is also recorded 
> for replay through the week.
>
> No download to use.
>
> AGC is to happen when the Smart Speaker is playing it, real time.
> Any post-record editing would be a horrendous task to say the least.
>
My guess is you don't understand how "Podcasts" work. All they are is a web 
resource that your Browser/Smart Device makes a request off, and the contents 
are streamed over the internet to that device, which then plays it. Smart 
Speakers just have a program that knows how to access these.

Since they can be listened to on a web browser, a program can download the 
data. They might be doing things to make this harder, but that is a sign that 
you shouldn't be doing this in the first place.

Often, the data format that is streamed is exactly like the file format for 
storing an audio file (since that is what the code in the browser is built to 
handle).

It may be a bit of work to figure out the access methods to get the data, but 
this is the sort of job that computers were designed to do. 
Trying to make things that weren't designed to be remote controlled to be 
remote controlled may well be a lot more work.

--
Richard Damon

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Automatic Gain Control in Python?

2022-05-28 Thread Steve GS
>> Why would post-record editing be "horrendous"?

This has to be done on-the-fly before it is recorded. 
After the AGC is applied, it will be played, live, to the community.
It is played during the week to a much smaller audience, almost as
background noise.
Post recording editing would be a waste of time and worthless.

>> Does it record the whole 48 hours into 1 file?

Two files, 24 hours each, one for Saturday, the other Sunday


-Original Message-
From: Python-list  On
Behalf Of MRAB
Sent: Saturday, May 28, 2022 8:57 PM
To: python-list@python.org
Subject: Re: Automatic Gain Control in Python?

On 2022-05-29 01:17, Steve GS wrote:
> "My first thought is you are solving the wrong problem. What seems a 
> better option would be to get your code to actually connect up to the 
> podcast and just download the audio directly, rather than trying to 
> get the smart speaker to play the audio and record it with a microphone."
> 
> The smart-speaker is bringing in the podcast by hourly automated 
> commands and sending by audio cable to a computer which is recording 
> it with Audacity.  This is an automated system that runs for 48 hours
every weekend.
> Its output is played live throughout the facility and is also recorded 
> for replay through the week.
> 
> No download to use.
> 
> AGC is to happen when the Smart Speaker is playing it, real time.
> Any post-record editing would be a horrendous task to say the least.
> 
[snip]
Why would post-record editing be "horrendous"?

Does it record the whole 48 hours into 1 file?

If it's recording each podcast separately, it could process each one after
recording it, even while the next one is being recorded, and I really doubt
that processing each one while take long.
--
https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Automatic Gain Control in Python?

2022-05-28 Thread MRAB

On 2022-05-29 01:17, Steve GS wrote:

"My first thought is you are solving the wrong problem. What seems a better
option would be to get your code to actually connect up to the podcast and
just download the audio directly, rather than trying to get the smart
speaker to play the audio and record it with a microphone."

The smart-speaker is bringing in the podcast by hourly automated commands
and sending by audio cable to a computer which is recording it with
Audacity.  This is an automated system that runs for 48 hours every weekend.
Its output is played live throughout the facility and is also recorded for
replay through the week.

No download to use.

AGC is to happen when the Smart Speaker is playing it, real time.
Any post-record editing would be a horrendous task to say the least.


[snip]
Why would post-record editing be "horrendous"?

Does it record the whole 48 hours into 1 file?

If it's recording each podcast separately, it could process each one 
after recording it, even while the next one is being recorded, and I 
really doubt that processing each one while take long.

--
https://mail.python.org/mailman/listinfo/python-list


RE: Automatic Gain Control in Python?

2022-05-28 Thread Steve GS
"My first thought is you are solving the wrong problem. What seems a better
option would be to get your code to actually connect up to the podcast and
just download the audio directly, rather than trying to get the smart
speaker to play the audio and record it with a microphone."

The smart-speaker is bringing in the podcast by hourly automated commands
and sending by audio cable to a computer which is recording it with
Audacity.  This is an automated system that runs for 48 hours every weekend.
Its output is played live throughout the facility and is also recorded for
replay through the week.

No download to use.

AGC is to happen when the Smart Speaker is playing it, real time.
Any post-record editing would be a horrendous task to say the least.

=

Genie: You have three wishes.
Me: I wish I had more wishes.
Genie: You cannot wish for more wishes.
Me: I wish I could.

-Original Message-
From: Python-list  On
Behalf Of Richard Damon
Sent: Saturday, May 28, 2022 6:53 PM
To: python-list@python.org
Subject: Re: Automatic Gain Control in Python?

On 5/28/22 5:29 PM, Steve GS wrote:
> I have an extensive Excel/VBA program that hourly calls and plays 
> podcasts through a "smart" speaker. The output of the speaker feeds 
> into another computer that records the m\audio using Audacity.
>
> It has become obvious that NPR does not regulate volumes for podcasts 
> and broadcasts nor are programs in themselves regulated by volume.  
> Audacity does not have an AGC.
>
> It has also been noted that Excel/VBA code cannot see the audio being 
> played on the same computer.
>
> I would like to find code that will regulate the volume and give some 
> semblance of control/moderation. Also, sometimes the Smart Speaker 
> fails to play the program and I get an hour of silence before the next 
> command to play happens. The code should detect that nothing is 
> playing and send the command to the smart speaker again.
>
> Is there any Python code that I might be able to call from VBA that 
> will monitor and regulate the volume of the audio? A few samples of 
> code that can read/modify the audio will help me develop the final
product.
>
> Suggestions appreciated.

My first thought is you are solving the wrong problem. What seems a better
option would be to get your code to actually connect up to the podcast and
just download the audio directly, rather than trying to get the smart
speaker to play the audio and record it with a microphone. That might
require finding the API for the site that hosts the podcasts, to get it to
send the files to you to "play".

Once you have the files, it becomes simple signal processing to go over the
files and AGCing them as needed.

On a side note, make sure you are within your rights within Copyright law
for what you are doing. Recording for PERSONAL use is probably within the
bounds of "Fair Use", but the material is surely under Copyright, so be
careful what you do with it.

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Automatic Gain Control in Python?

2022-05-28 Thread Richard Damon

On 5/28/22 5:29 PM, Steve GS wrote:

I have an extensive Excel/VBA program that hourly calls and plays podcasts
through a "smart" speaker. The output of the speaker feeds into another
computer that records the m\audio using Audacity.

It has become obvious that NPR does not regulate volumes for podcasts and
broadcasts nor are programs in themselves regulated by volume.  Audacity
does not have an AGC.

It has also been noted that Excel/VBA code cannot see the audio being played
on the same computer.

I would like to find code that will regulate the volume and give some
semblance of control/moderation. Also, sometimes the Smart Speaker fails to
play the program and I get an hour of silence before the next command to
play happens. The code should detect that nothing is playing and send the
command to the smart speaker again.

Is there any Python code that I might be able to call from VBA that will
monitor and regulate the volume of the audio? A few samples of code that can
read/modify the audio will help me develop the final product.

Suggestions appreciated.


My first thought is you are solving the wrong problem. What seems a better option would 
be to get your code to actually connect up to the podcast and just download the audio 
directly, rather than trying to get the smart speaker to play the audio and record it 
with a microphone. That might require finding the API for the site that hosts the 
podcasts, to get it to send the files to you to "play".

Once you have the files, it becomes simple signal processing to go over the 
files and AGCing them as needed.

On a side note, make sure you are within your rights within Copyright law for what you 
are doing. Recording for PERSONAL use is probably within the bounds of "Fair 
Use", but the material is surely under Copyright, so be careful what you do with it.

--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list


Re: .0 in name

2022-05-28 Thread Chris Angelico
On Sun, 29 May 2022 at 08:26, Eryk Sun  wrote:
>
> On 5/28/22, Chris Angelico  wrote:
> >
> > be extremely confusing; so to keep everything safe, the interpreter
> > generates a name you couldn't possibly want - same as for the function
> > itself, which is named "" or "", angle brackets
> > included.
>
> To clarify, "" is the co_name and co_qualname value of the
> code object, which was compiled for the list comprehension. These
> names are also used as the __name__ and __qualname__ of the temporary
> object that's created by MAKE_FUNCTION. They are not identifiers. The
> code object is a constant, which is referenced solely by its index in
> the co_consts tuple. The temporary function is referenced on the
> stack.

Correct. Every function has a name, important for tracebacks and such,
but with lambda functions, the internal functions of comprehensions,
and so on, there's no actual name binding for it. So the interpreter
generates a name that won't collide with any actual name that you'd
have assigned anything to.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: .0 in name

2022-05-28 Thread Eryk Sun
On 5/28/22, Chris Angelico  wrote:
>
> be extremely confusing; so to keep everything safe, the interpreter
> generates a name you couldn't possibly want - same as for the function
> itself, which is named "" or "", angle brackets
> included.

To clarify, "" is the co_name and co_qualname value of the
code object, which was compiled for the list comprehension. These
names are also used as the __name__ and __qualname__ of the temporary
object that's created by MAKE_FUNCTION. They are not identifiers. The
code object is a constant, which is referenced solely by its index in
the co_consts tuple. The temporary function is referenced on the
stack.
-- 
https://mail.python.org/mailman/listinfo/python-list


Automatic Gain Control in Python?

2022-05-28 Thread Steve GS
I have an extensive Excel/VBA program that hourly calls and plays podcasts
through a "smart" speaker. The output of the speaker feeds into another
computer that records the m\audio using Audacity.

It has become obvious that NPR does not regulate volumes for podcasts and
broadcasts nor are programs in themselves regulated by volume.  Audacity
does not have an AGC.

It has also been noted that Excel/VBA code cannot see the audio being played
on the same computer.  

I would like to find code that will regulate the volume and give some
semblance of control/moderation. Also, sometimes the Smart Speaker fails to
play the program and I get an hour of silence before the next command to
play happens. The code should detect that nothing is playing and send the
command to the smart speaker again.

Is there any Python code that I might be able to call from VBA that will
monitor and regulate the volume of the audio? A few samples of code that can
read/modify the audio will help me develop the final product.

Suggestions appreciated.




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: .0 in name

2022-05-28 Thread Chris Angelico
On Sun, 29 May 2022 at 06:41, Ralf M.  wrote:
>
> Am 13.05.2022 um 23:23 schrieb Paul Bryan:
> > On Sat, 2022-05-14 at 00:47 +0800, bryangan41 wrote:
> >
> >> May I know (1) why can the name start with a number?
> >
> > The name of an attribute must be an identifier. An identifier cannot
> > begin with a decimal number.
>
> I'm not sure about the first statement. Feeding
>
> [print("locals:", locals()) or c for c in "ab"]
>
> to the REPL, the result is
>
> locals: {'.0': , 'c': 'a'}
> locals: {'.0': , 'c': 'b'}
> ['a', 'b']
>
> i.e. there is a variable of name .0 in the local namespace within the
> list comprehension, and .0 is definitely not an identifier.
>
> I came across this while investigating another problem with list
> comprehensions, and I think the original post was about list comprehensions.
>

There are a few quirks with comprehensions, and to understand that
".0", you have to first understand two very important aspects of
scoping with regard to comprehensions.

(Note: For simplicity, I'm going to refer in general to
"comprehensions", and I am not going to count Python 2. My example
will be a list comp, but a generator expression also behaves like
this, as do other comprehensions.)

Consider this function:

def spam():
ham = "initial"
ham = [locals() for x in "q"]
return ham

The disassembly module can be very helpful here. The precise output
will vary with Python version, but the points I'm making should be
valid for all current versions. Here's how it looks in a December
build of Python 3.11 (yeah, my Python's getting a bit old now, I
should update at some point):

>>> dis.dis(spam)
  2   0 LOAD_CONST   1 ('initial')
  2 STORE_FAST   0 (ham)

  3   4 LOAD_CONST   2 ( at
0x7fb6a0cfa6b0, file "", line 3>)
  6 MAKE_FUNCTION0
  8 LOAD_CONST   3 ('q')
 10 GET_ITER
 12 CALL_FUNCTION1
 14 STORE_FAST   0 (ham)

  4  16 LOAD_FAST0 (ham)
 18 RETURN_VALUE

Disassembly of  at 0x7fb6a0cfa6b0, file
"", line 3>:
  3   0 BUILD_LIST   0
  2 LOAD_FAST0 (.0)
>>4 FOR_ITER 5 (to 16)
  6 STORE_FAST   1 (x)
  8 LOAD_GLOBAL  0 (locals)
 10 CALL_FUNCTION0
 12 LIST_APPEND  2
 14 JUMP_ABSOLUTE2 (to 4)
>>   16 RETURN_VALUE
>>>

Okay, that's a lot of raw data, but let's pull out a few useful things from it.

Line 2 initializes ham in an unsurprising way. Grab a constant, store
it in a local. Easy.

Line three. We grab the code object for the list comp, and make a
function (that's necessary for closures). Then, *still in the context
of the spam function*, we grab the constant "q", and get an iterator
from it. Leaving that on the top of the stack, we call the list
comprehension's function, and store the result into 'ham'.

The comprehension itself loads the fast local from slot zero (name
".0")  and iterates over it. Slot zero is the first argument, so
that's the string iterator that we left there for the function.

So why IS this? There are a few reasons, but the main one is generator
expressions. Replacing the list comp with a genexp gives this result:

>>> spam()
. at 0x7fb6a0780890>

The actual iteration (row 4 in the genexp in the above disassembly of
) doesn't happen until you iterate over this value. But it
would be extremely confusing if, in that situation, errors didn't show
up until much later. What if, instead of iterating over a string, you
tried to iterate over a number? Where should the traceback come from?
Or what if you're iterating over a variable, and you change what's in
that variable?

def wat():
stuff = "hello"
ucase = (l.upper() for l in stuff)
stuff = "goodbye"
return "".join(ucase)

Does this return "HELLO" or "GOODBYE"? Since stuff gets evaluated
immediately, it returns HELLO, and that's consistent for list comps
and genexps.

But because of that, there needs to be a parameter to carry that
iterator through, and every parameter needs a name. If the generated
name collided with any identifier that you actually wanted, it would
be extremely confusing; so to keep everything safe, the interpreter
generates a name you couldn't possibly want - same as for the function
itself, which is named "" or "", angle brackets
included.

That's a fairly long-winded way to put it, but that's why you can have
variables with bizarre names :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: .0 in name

2022-05-28 Thread Ralf M.

Am 13.05.2022 um 23:23 schrieb Paul Bryan:

On Sat, 2022-05-14 at 00:47 +0800, bryangan41 wrote:


May I know (1) why can the name start with a number?


The name of an attribute must be an identifier. An identifier cannot
begin with a decimal number.


I'm not sure about the first statement. Feeding

[print("locals:", locals()) or c for c in "ab"]

to the REPL, the result is

locals: {'.0': , 'c': 'a'}
locals: {'.0': , 'c': 'b'}
['a', 'b']

i.e. there is a variable of name .0 in the local namespace within the 
list comprehension, and .0 is definitely not an identifier.


I came across this while investigating another problem with list 
comprehensions, and I think the original post was about list comprehensions.


There also can be non-identifier names in the global namespace and as 
attributes, e.g. using the REPL again:


globals()["42"] = "The Answer"
globals()

outputs (see last entry)

{'__name__': '__main__', '__doc__': None, '__package__': None, 
'__loader__': , '__spec__': 
None, '__annotations__': {}, '__builtins__': (built-in)>, '42': 'The Answer'}


and

class Cls:
def __init__(self, lst):
for i, e in enumerate(lst):
self.__dict__[str(i)] = e

obj = Cls([31, 42, 53])
getattr(obj, "1")

works and outputs

42


(2) where in the doc is it?!


https://docs.python.org/3/reference/lexical_analysis.html#identifiers


That refers to identifiers, i.e. names that are recognised as such by 
the lexer, i.e. that can be written directly in Python source code.


As shown above, names that are not identifiers can be used in several 
namespaces and as attributes. It's just a bit harder to use 
non-identifier names than identifiers.

Whether it's a good idea to use them at all is a different question.

I think the OP wondered about the .0 in the local namespace within list 
comprehensions. Unfortunately I cannot say much about that.



Paul


Ralf M.
--
https://mail.python.org/mailman/listinfo/python-list


Re: terminate called after throwing an instance of 'boost::python::error_already_set

2022-05-28 Thread Barry


> On 27 May 2022, at 21:17, Larry Martell  wrote:
> 
> I have a script that has literally been running for 10 years.
> Suddenly, for some runs it crashes with the error:
> 
> terminate called after throwing an instance of 
> 'boost::python::error_already_set
This is from an extension that is written in C++ that raised a C++exception, not
a python one. The default action in C++ is to terminal the process so python
does not get a chance to prints its stack.

> 
> No stack trace. Anyone have any thoughts on what could cause this
> and/or how I can track it down?

You will need to use a C++ level debugger to see which extension is crashing.
gdb on linux, lldb on macOs or visual studio on windows.

Barry


> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

-- 
https://mail.python.org/mailman/listinfo/python-list