|
I see
Well, there is no notion of the default mixer's line, it is selected. To be honest, I haven't investigated the problem of identifying currently selected mixer's line, but, in sources you will find how to select a line you need. Same you can find at this link
http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B159753
See the code for "void SelectMic()" function. That code is a bit huge and maybe not quite descriptive but see the bottom of the code:
for (DWORD j=0; j
|
|
|
|
|
Problems with text formatting ... sorry about that. Here is what to check for:
for (DWORD j=0; j < cMultipleItems; j = j + cChannels)
........if (0 == strcmp(plisttext[j].szName, "Microphone"))
................// Select it for both left and right channels
................plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 1;
........else if (bOneItemOnly)
................// Mux or Single-select allows only one item to be selected
................// so clear other items as necessary
................plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 0;
|
|
|
|
|
im new to mp3, very new....
i downloaded the code, add the lame....dll
and run it..
and it does not create exe file..
here is the output..
////////////////////////////////////////////////////
'mp3_stream.exe': Loaded 'C:\Documents and Settings\lyeaos\Desktop\mp3_stream_src\Debug\mp3_stream.exe', Symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\winmm.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\Program Files\TuneUp Utilities 2006\WinStylerThemeHelper.dll', Binary was not built with debug information.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
'mp3_stream.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded.
The program '[2308] mp3_stream.exe: Native' has exited with code 0 (0x0).
////////////////////////////////////////////////////////////////////////////////
pls help me
leoren_tm
|
|
|
|
|
Hi,
Added lame_enc.dll? You shouldn't add lame_enc.dll anywhere, the link is done dynamically (invoked from code).
Are you using VS.NET (2003 or 2005) to compile? Or?
Top of the article says VS 6.0 in fact. So, I am not sure VS.NET (C++) compiler will compile VS 6.0 project without changes. I would recommend to create VS.NET solution from scratch and just copy/paste existing code.
Regards,
Ruslan Ciurca
|
|
|
|
|
im confuse...where should i use lame_enc.dll? beside the excutable files?
im using visual studio 2005 profesional editionn...
it is posible to have an error because i compiled it on a higher versin?
im new to visaul...pls help me.
ADA
|
|
|
|
|
ADA,
>>im confuse...where should i use lame_enc.dll? beside the excutable files?
As i wrote, lame_enc.dll is dynamically loaded from the code using relevant API (LoadLibrary(...) from Win SDK). lame_enc.dll isn't a .NET assembly, it is a native DLL, so, you shouldn’t add it anywhere; just make sure lame_enc.dll is in the same folder with the executable (exe) before you start executable.
>>im using visual studio 2005 profesional editionn...
>>it is posible to have an error because i compiled it on a higher versin?
>>im new to visaul...pls help me.
Yep ... very possible if you open VS 6.0 project with VS.NET 2005. That's why i recommend you creating a new solution and copy/paste existing code.
Regards,
Ruslan
|
|
|
|
|
Hi,
Just to let you know: your sample project works perfectly fine when compiled with Visual Studio 2005, and no change is required (other than going through the VS upgrade wizard).
|
|
|
|
|
Nice ... thank you for this update.
Regards,
Ruslan
|
|
|
|
|
I feel this article very good. I want to use lame_enc.dll file in my project. Can you show me how to use it. Thank you very much.
Note : I want that when music is playing then program begins work and when music have just stoped then program stops work.
Thank you very much once more
-- modified at 2:39 Wednesday 28th February, 2007
|
|
|
|
|
Hi,
Well, regarding showing how to use. I think best you download sources and have a look at the "mp3_simple.h" file. Anyway I will end up explaining that file. Or, even better use those sources in your project.
Regarding what you want to implement ... biggest problem is detecting when music is stopped. This is a silence detection algorithm and if you google, you can find code or good advices how to do, I don't have one to be honest. But, keep in mind, access to the soundcard's recording device (Wave IN) is exclusive. So, if there is another application recording, your program will not be able to record. Those are two technical issues you may encounter.
Regards,
Ruslan
|
|
|
|
|
Hi Ruslan,
I am working on a new project in which i need to,
Record from both Microphone and waveout simultaniously and either save it into a file or send through socket ( something like inserting an audio comment on what u r listening ).
How can i record from MIC and WAVEOUT simultaniously ?
Can you plz give me some advice regarding this?
Mujeeb.
|
|
|
|
|
Hi Mujeeb,
Well, almost impossible, but depends on sound card. So far, I haven't seen cards with options to record from multiple sources. You can test it by opening Volume Control -> Options -> Properties -> Recording -> OK.
However, there is a solution and it is related to the microphone only. It is so called microphone routing and again depends on sound card. Check
Volume Control -> Options -> Properties -> Playback. If you see microphone there then you can route the microphone. This means that recorded sound from the microphone will be routed to the WAVEOUT by the sound card's driver. This also means that sound card will mix music going to WAVEOUT (from e.g. WinAmp) with the sound from the microphone. The quality depends on the soundcard but in many cases it is fine.
Other solution would be to write a sound card driver, but this isn't the easiest one.
Regards,
Ruslan
|
|
|
|
|
Thanks Ruslan,
you give me the right advice
i think the second option is possible bcz, now all sound cards have stereo Mix in Recording source and Microphone playback, I tried it in my system
1. Enable Mic in Playback
2. Set Recording source as stereo mix
3. Start playback using winamp
4. Record stereo mix using sound recorder
and i got the result i want.
Now i need some help on implementing this in my VB.NET project. Am i use DirectX for the same or is there is any other technology exist for doing it?
if you can give me some samples, i will be thankful.
Regards,
Mujeeb
|
|
|
|
|
Unfortunately, I am helpless regarding VB.NET. I am using C++ and Java most of the time ... some C#, but most for Windows Smart Phones. I suggest you find some starting point applications in C#, so you'll translate them to VB. Otherwise (in case you don't find anything good) you can use [DllImport] (or equivalent in VB.NET) for importing relevant functions from the relevant DLL's. Sorry about that.
Regards,
Ruslan
|
|
|
|
|
waveform audio interface you can hear in your .net apps[^][^]
Testing your code against performance will keep you running with good scalability and maintenance for years.
NTime.exe - the free tool for real developers of high scalability applications!
Testing your code against performance will keep you running with good scalability and maintenance for years.
NTime.exe - the free tool for real developers of high scalability applications!
|
|
|
|
|
Hi, is it possible to write IDv2 tags through mp3_simple or wavein_simple?
Thanks in advance.
Rafael
|
|
|
|
|
Nope, I haven't designed those classes to support writing IDv1/2 tags. I need to think on re-adapting them, as, much probably, I will need tagging too.
Regards,
Ruslan
|
|
|
|
|
Hi!
I was wondering if there is much to to get the project running on a pocket pc
|
|
|
|
|
Honestly, I don't know, I haven't investigated (yet) this option. Apart ... maybe ... if to port LAME to Pocket PC. I am not sure this will work well, LAME API uses processor pack instructions (MMX, SSE1/2) for a good reason and CPU power of the PPC's are yet too weak.
Regards,
Ruslan
|
|
|
|
|
Hi,
I've been looking for LAME in the last weeks but my c++ is not good enough to appreciate the source (i'm more on the c# side), the incipit of your article is very near to what i need, i.e. listen to a microphone on computer 1 and get the live voice on computer 2.
Thanks to your sample (much easier to read) now i can easily intercept microphone or linein audio and stock it in a file, but what if i must listen to it live for many minutes from another pc, while not creating a gicantic mp3 ?
Can you give me some directions and/or anticipations on what aspects i must study to reach this ? I'm... quite pressed
Thanks in advance, and good year!
Fabrizio
|
|
|
|
|
Hello Fabrizio,
First big change in your application would be not to save recorded sound in a file, but in memory buffers. Let say, you need to create some buffers to hold last X (e.g. 5) seconds of the recorded sound. For example, I created a class with X buffers where each buffer holds 1 second of the recorded sound. Each buffer also contains timestamp, so I always know which one is the most recent and which one is oldest. If new sound data is coming and there are no free buffers, the oldest one is overridden (call it cycle buffering). If you are encoding at a specific bitrate, you will know of what size should be the buffer to hold 1 second of sound (e.g. 128Kbps * 1 sec = 128 Kilo bits = 128000 bits => (divide by 8) => 16000 bytes).
Second. This depends on how you want to implement your server application. If you have you own client application, then it is enough to be well familiar with sockets API. If you want WinAmp and Windows Media Player to be able to play that sound, you will need some basic knowledge of (e.g.) HTTP protocol with few additional IceCast commands (e.g. google for "icy-name:", "icy-pub:" and "icy-br:"). Most important here is, you should implement a tracking mechanism, so you will always know what was the last sound buffer you sent to a particular socket (see buffering idea above).
Third. You need to be familiar with at least one of the patterns for developing server applications. Easiest one is "one thread serves one client connection" which may work fine for ~100-1000 concurrent connection (depends on hardware as well as how you implement your application). I recommend you to start with this one. However, later you can switch to asynchronous sockets ("one thread serves few (10, 20 etc.) connections" or "event based sockets"). For really scalable server application, you can also try IO Completion Ports, but this will be more complex. By the way, I have posted the second article of this series at http://www.codeproject.com/useritems/LikeJavaThreads.asp. There you will find sources of the thread pool class I am using in my streaming server application. However, I am sure .NET may provide better thread pool classes.
Regards,
Ruslan
|
|
|
|
|
Hello Ruslan,
thanks for your quick and exaustive response, i saw you wrote another article but by the title (Java threads) i guessed it was about something different and didn't check. doh.
First: Even if i never played with them in c++m cycle buffering is a kind of procedure i know and i hope i won't create me big troubles. I'm more lost on how to save 1 sec music in a buffer element.
Second: here i'm a bit more lost, what i need is my own client application and through tcp i know how to chat between apps. what i don't know is how to send the 1 sec buffer element to the speakers and how to be sure to have sound without silence gaps or start singing before the previous has ended.
Third: I'm quite confident with async threading (having built more than a service with tcp client/server), still i have few experience in c++ and your 2nd article will be surely useful.
Again, thanks for the time you can spend on the argument, you've already been very helpful.
Fabrizio
|
|
|
|
|
Ok, let's see:
1. If you are implementing based on the code from this article, mind
CWaveINSimple::CWaveINSimple(...) {
...
this->m_waveFormat.nAvgBytesPerSec = this->m_waveFormat.nSamplesPerSec * this->m_waveFormat.nBlockAlign;
...
this->m_WaveHeader[1].dwBufferLength = this->m_WaveHeader[0].dwBufferLength = this->m_waveFormat.nAvgBytesPerSec << 1;
}
This means that every returned buffer with PCM from sound card will contain max 2 seconds of sound (m_waveFormat.nAvgBytesPerSec << 1 == m_waveFormat.nAvgBytesPerSec * 2). Every second of PCM encoded in MP3 will be exactly 1 second of MP3 sound. So, cycle buffering class must hold at least 2 seconds of MP3, otherwise there is a risk (99.9%) to override sound that wasn't yet sent (so 5 seconds should be fine). You are right about saving 1 second of data in a buffer, you need to analyse incoming buffer size and split it in 1 second buffers and pass each of them to the cycling buffer class. Not a big problem, but you should be very careful with C/C++ pointers here. Best (easy) way to avoid this is to use pipes (see MSDN for CreatePipe() function). So re-adapted IReceiver would look like:
enum IO_MODES {READ, WRITE};
class mp3Writer: public IReceiver {
private:
CMP3Simple m_mp3Enc;
HANDLE pipes[2];
public:
mp3Writer(unsigned int bitrate = 128, unsigned int finalSimpleRate = 0):
m_mp3Enc(bitrate, 44100, finalSimpleRate) {
if (!(CreatePipe(&pipes[READ], &pipes[WRITE], NULL, 44100 * 4))) {
throw "wavein_listener, no resources.";
}
};
~mp3Writer() {
CloseHandle(pipes[WRITE]);
CloseHandle(pipes[READ]);
};
HANDLE getReadPipeEnd() { return pipes[READ]; };
virtual void ReceiveBuffer(LPSTR lpData, DWORD dwBytesRecorded) {
BYTE mp3Out[44100 * 4];
DWORD dwOut;
DWORD dwRet;
m_mp3Enc.Encode((PSHORT) lpData, dwBytesRecorded/2, mp3Out, &dwOut);
WriteFile(pipes[WRITE], mp3Out, dwOut, &dwRet, NULL)
};
};
This time mp3Writer will push encoded sound to a pipe. Now you need another thread that will actually read sound from that pipe, something like:
// OneSecondSize must be equal to 1 second of MP3, it depends on bitrate!!!
BYTE MP3Buffer[OneSecondSize];
ReadPipe = mp3WriterInstance->getReadPipeEnd();
while (1) {
memset(MP3Buffer, 0, sizeof(MP3Buffer));
if (::ReadFile(ReadPipe, MP3Buffer, sizeof(PCMBuffer), &dwRead, NULL))
{
// normally it must be so dwRead == sizeof(PCMBuffer), reading from/writing
// to pipe is blocking operation. dwRead < sizeof(PCMBuffer) only when reading
// last bytes from pipe, but not a big problem anyway.
// Now MP3Buffer contains 1 second of MP3. Cache it in a cycle buffer class!!!
}
else {
// most probably pipe was closed
break;
}
}
All the above are not checked/compiled code, if you find errors – sorry for that. But these pseudo codes should highlight the idea.
Next answers i will post separately, this one is too big already.
Regards,
Ruslan
|
|
|
|
|
>> Second: here i'm a bit more lost, what i need is my own client application and through tcp i know how to chat between apps. what i don't know is how to send the 1 sec buffer element to the speakers and how to be sure to have sound without silence gaps or start singing before the previous has ended.
At the client side you need to know at what bitrate the sound was compressed. Otherwise you will not be able to guess the 1 second buffer size. But that shouldn't be a problem anyway. Problem is decoding, to be more precise the way sound will be decoded. With MadXLib (see other messages I posted here, you will find the link to that lib) you can do it like other players, allocate a buffer and cache incoming data there (pre-loading). Send a part of that buffer to the MadXLib decoding function and it will tell you is it enough data or not to decode a complete chunk. If not enough, get another part from the buffer or wait for data to come from server. Once you obtain PCM sound from decoder, send it to the soundcard (check Wave Out functions). With other decoding libraries - you should check the API. Regarding gaps, I would say you must consider them (even theoretically) because they may happen (network problems, other download/upload operations increasing/reducing the traffic. etc).
>>Third: I'm quite confident with async threading (having built more than a service with tcp client/server), still i have few experience in c++ and your 2nd article will be surely useful.
Then it should be easier for you. However, I would try to find some C# classes wrapping LAME API and would implement all in C#. By the way, regarding MadXLib API, guys created MadXLib have few nice classes and implementations in C# (you will find on their site).
Regards,
Ruslan
|
|
|
|
|
Just two more lines to thank you again.
From here i'll try to not abuse of your help and walk on my legs; if i get lost i'll scream for help
Regards,
Fabrizio
|
|
|
|
|