Wikipedia:Reference desk/Archives/Computing/2006 September 29

< September 28 Computing desk archive September 30 >
Humanities Science Mathematics Computing/IT Language Miscellaneous Archives
The page you are currently viewing is an archive page. While you can leave answers for any questions shown below, please ask new questions at one of the pages linked to above.
< August September October >


Battery woes with technology edit

I've just gotten a new 30GB movie iPod, and I'm so excited! But I've received a lot of different comments about how often I should charge it. One person told me that I should let the battery drain all of the way to dead before charging it, and the other said that the iPod should be charged a lot so it always has some charge. What's the better idea? I've heard a lot more about the drain-it-all idea, but the person who constantly charged her iPod said she still has the same iPod from two and a half years ago and it works great. The ikiroid (talk·desk·Advise me) 00:28, 29 September 2006 (UTC)[reply]

What type of batteries does it have ? StuRat 01:09, 29 September 2006 (UTC)[reply]
Apple have a page about battery care in iPods, and a page about lithium-ion batteries in general. Also, see our article on Lithium ion battery. --Canley 03:59, 29 September 2006 (UTC)[reply]

Ah, so I shouldn't drain it, according to the article. OK, thank you Canley. The ikiroid (talk·desk·Advise me) 19:31, 29 September 2006 (UTC)[reply]

BitTorrent edit

I have been considering joining a BitTorrent project lately, but a question has come up that the project in question's FAQ that seems to be neatly avoided. Is BitTorrent file sharing legal, or not? I am under the impression now that it is legal as long as you do not sell the product, but I don't know. It would be nice to know the legality of BitTorrent before I engage in any activity with it. Thank you! PullToOpen talk 00:57, 29 September 2006 (UTC)[reply]

There is nothing illegal about BitTorrent. The legal question comes into copying software that you do not hold the legal copyright to copy. Yes, sharing files online is legally copying thing (I am amazed that people who are smart enough to use a computer claim "You can't copy files - they are just electronic ones and zeros"). If you do not have the right to copy something, it is illegal to copy it or to help someone else copy it. By sharing files on BitTorrent, you are either copying or helping someone else copy the files. It may not be what you want to hear, but the law couldn't be simpler. I'll never understand why it is so hard for people to understand that if you don't have the copyright you don't have the right to copy. --Kainaw (talk) 01:50, 29 September 2006 (UTC)[reply]
What he said. You fast one you. — X [Mac Davis] (SUPERDESK|Help me improve)01:51, 29 September 2006 (UTC)[reply]
That's incorrect. I don't have the copyright for Ubuntu, but I have the right to copy it. --cesarb 15:41, 29 September 2006 (UTC)[reply]
You do in fact have a license to distribute ubuntu, read the GPL. Anyway what you said makes no sense- "I dont have the copyright... but I have the right to copy." What? --frothT C 19:03, 29 September 2006 (UTC)[reply]
He didn't copyright it, but he still has the right to copy. --Kjoonlee 03:29, 30 September 2006 (UTC)[reply]
It is apparent that some people don't take the time to read copyright before assuming they have a clue what it means to have a copyright - which is the shortened for of "to have a copying right". For example, I can write a book (which gives me the copyright) and then give a distributor copyright to copy and sell it. I'm not giving away my copyright (unless it is in the contract that I have to give up my copyright in a noncompete sort of thing). That is how Ubuntu (and GPL) works. The author has the copyright but gives it away to anyone who wants it with the GPL. --Kainaw (talk) 22:43, 30 September 2006 (UTC)[reply]

What sort of project do you mean? If you plan to help develop a Bittorrent client, such as uTorrent, that's perfectly legal. If you plan to help organise and maintain a Bittorrent tracker, such as Suprnova or Mininova, you may end up facing prosecution or at least the threat of prosecution.

Windows clock one our late edit

My system clock in Windows 2000 is one our late . I set it properly but the next day the same story. I do not have the "Automatically adjust clock for daylight saving changes" option enabled

What could be the problem?

Thank you

Try enabling it! Mabye your clock is automatically synchronizing itself every day or so, and since daylight saving is off, it shows winter time. That's my guess, anyway. —Bromskloss 11:56, 29 September 2006 (UTC)[reply]
Perhaps uncheck the checkbox in the Internet Time tab (although that MAY be an XP only feature. Chris M. 14:39, 29 September 2006 (UTC)[reply]
Disabling it can be bad; some things do not work correctly if your computer's time is incorrect (the one I heard of most recently is cookie expiry in web browsers). --cesarb 20:40, 30 September 2006 (UT

try making sure you have the right time zone.

Windows Update Issue? edit

A computer here worked fine on Monday. It sat idle all week (but did have Windows Auto-Update running). Now, it will not accept any USB thumbdrives. Was there a MS patch this week that restricts USB access? --Kainaw (talk) 14:02, 29 September 2006 (UTC)[reply]

Updating this question, just found out it is Win2000 and a Sandisk Cruzer Micro 1GB. --Kainaw (talk) 14:33, 29 September 2006 (UTC)[reply]

Accessing My Data In Another Country edit

If I have a bulky computer that I don't want to transport for study in another country, is there a set up that I could acheive to allow me to access data on my harddrives (if have five to total 800 GB so transport of data/drives not really practical) from a laptop in another country? --Username132 (talk) 15:58, 29 September 2006 (UTC)[reply]

Do you really need all of it ? I think you should prune it down to just as much as will fit on your laptop. StuRat 18:11, 29 September 2006 (UTC)[reply]
Try FreeNX --frothT C 19:58, 29 September 2006 (UTC)[reply]
That gives "near local speed application responsiveness over high latency, low bandwidth links", which, I think, means that it reacts fast. But what you want is the other kind of speed, not reaction time but bytes per second, in other wirds high bandwidth. That is, if you don't just want to acces bits of the data from a distance, but transport it all. 800GB over the Internet would take waaaay too long. If cost is not a major issue, why not buy one really big hard drive, transfer it all to that locally and take that with you. 800GB is just possible now, or else buy two 400GB ones, which would also bring the price down from roughly 400 to 250 euro. dvd's would bring the price down further to about 150 euro (maybe even less if you buy bulk), but I know from experience that that would be way to cumbersome, especially chopping up the data in 5GB chunks. And of course it takes a whole lot of time and I don't know what price tag you put on your time. Whatever option you use, you can always try data compression (eg to make it fit on a smaller disk). I have no experience with that, but I assume that would also consuyme your precious time and you may have to unpack it again when you reach your destination. DirkvdM 08:30, 30 September 2006 (UTC)[reply]
If you want speedy transfer of nearly a TB of data, nothing will compare to the convenience of an external hard drive --frothT C 16:59, 1 October 2006 (UTC)[reply]

Sending emails tips edit

While sending emails to many people at once I use one of the receipients' address in the "To" field and other addresses on "BCC" field.Is there any way to send mails to different people so that the receipient may think that that mail is specially sent to him and not to others.Here i mean to say that in some cases in place of eg "Dear John" can i insert the receipients' name as a field eg "Dear {Receipient}.May be i could not put the matter exactly.Thanks

You put it plainly enough. You want to spam. There are many spam programs available on the Internet that allow you to do exactly what you are asking. --Kainaw (talk) 18:43, 29 September 2006 (UTC)[reply]
No spam programs needed, you can do this with Microsoft Office. Give it a list of emails and corresponding first names, and your form letter, and it can send out "personalized" copies of the form letter to every email address in the list. --Maelwys 20:10, 29 September 2006 (UTC)[reply]
That's jumping to conclusions. There's plenty of legitimate reasons why one would want to send emails to many people at once. Sum0 10:09, 30 September 2006 (UTC)[reply]
Yes, but what's of questionable legitimacy is making them all look personal. NeonMerlin 16:25, 30 September 2006 (UTC)[reply]
Yes, there are plenty of reasons. Just today, I got tons of offers for mortgages, viagra, baldness cures, fat reducers, a woman in my city who can't wait to meet me... I'm sure they are all legitimate. --Kainaw (talk) 22:39, 30 September 2006 (UTC)[reply]
There's those... or there's the actual legitimate reasons. I've used the Office Mail Merge function (that I referred to above) several times, when I had to send out personalized activity reports to 350 people, where each report had to reflect the activity of that specific individual. Mail Merge let me automatically pull the information (email address, individual's name, and associated records) from an excel database, create an individual email to that person, and send it, all at the press of a single button. It would've been days of work to do manually, and it certainly wasn't spam (though I had to send it out in batches of 50 an hour, so my ISP wouldn't think it was spam either ;-) ) --Maelwys 23:26, 30 September 2006 (UTC)[reply]
By the way, as you can gather by the comments here, if you are sending out bulk email you need to be very careful with your list management policies to avoid being misidentified as spam. This can result in your server being placed on spam blacklists, and thus many legitimate recipients will not be able to get your emails.
So make sure your email list is confirmed opt-in, as described by E-mail spam on Wikipedia. --Robert Merkel 01:40, 2 October 2006 (UTC)[reply]
My intention of asking was not sending spams.I really needed that help while sending greeting cards on the occasion of, say New Year, so that the receipient did not know that I have sent similar greetings to other people also.I wanted to make the receipient feel that it is special greeting sent only to him and not simple mass mail.It is not nice to blame others without knowing the fact. Mr. Kainaw.amrahs 17:35, 3 October 2006 (UTC)[reply]

Nintendo "64" edit

What does "64-bit" mean in the context of describing a video card? Surely the N64 didn't have more than 4GB of dedicated video memory.. why else use 64 bit wide registers if not to hold memory addresses 64 bits long? --frothT C 19:28, 29 September 2006 (UTC)[reply]

It's not only about having 64 bits to hold memory registers, remember a CPU/GPU is more than just a fancy switchboard (at times). More important to the N64 was the size of it's video processor, which was also 64 bits, and the MOST important was the width of the video bus which was 128 bits. An increased register size can make SIMD possible (for the cpu and gpu) at a low level, along with other math-intensive functions which are important to good graphic systems. They even touch on why strictly using a 64 bit cpu is bad for consoles, in Nintendo 64#Trivia.--Jmeden2000 20:19, 29 September 2006 (UTC)[reply]

You might be confusing the data bus with the address bus. IIRC, the data bus is how much data can move in/out of the processor in a cycle, while the address bus limits the amount of memory in the system. --Bennybp 21:34, 29 September 2006 (UTC)[reply]

Oh I see.. one thing though, this sounds entirely wrong to me: "64-bit data uses twice as much RAM, cache, and bandwidth thereby reducing performance" ... if 64-bit refers to the register size (which would affect the address length), it only increases address sizes by 32 bits, not "twice as much data". If it refers to the width of the data bus, then it still makes no sense! --frothT C 22:58, 29 September 2006 (UTC)[reply]
Umm... why would any video card need to be 64-bit? Screen resolution is nowhere near that fine, and no video card is going to have more than the 4GB limit on 32-bit addresses. What would be the point? - Rainwarrior 17:24, 30 September 2006 (UTC)[reply]
That's true of address sizes, but apparently it refers to the width of the data bus (64 bits of data can be outputted every cycle) --frothT C 16:57, 1 October 2006 (UTC)[reply]

The article on 64-bit shows that the term is pretty ambiguous. It looks like the term can either refer to the width of the various buses, or the size of some data types. IE a 64-bit data type can hold bigger values (2^64 possible values). I'm not positive what the 64 in N64 really meant, but from the N64 article (trivia section) it does look like it refers to the data type sizes, and that the buses are 32-bit. --74.69.54.30 20:15, 1 October 2006 (UTC)[reply]

In the beginning those bit numbers actually meant something. NES used an 8 bit processor, SNES used a 16-bit processor, PlayStation used a 32-bit processor. However, starting with Nintendo 64 (which actually had a 32 bit processor, if you look at the article), those numbers were simply used as a marker for generations and not any specific hardware issue (occasionally, the PS2 is referred to as a "128-bit" machine, but as you can understand, that makes no sense). This is also why it has fallen out of use, no one refers to the PS3 as a "256-bit" console or a "512-bit" console. Sadly, the days of measuring bad-assesness in terms of word size of the processor are over. Let's have a moment of silence........ Oskar 15:25, 3 October 2006 (UTC)[reply]

*nix root and overflow attacks edit

I've recently become interested in computer security.. one of the kinds of attacks I've read about is the buffer overflow attack. The attacker writes more than the allocated space for a variable so the input spills over possibly into code that's about to be executed. This allows the attacker to overwrite that code with code of his own, and this is called being able to execute arbitrary code on the target machine. Now what I'm confused about is that "running arbitrary code" is automatically associated with gaining root permissions. What about users on a *nix system that can execute any code that they want without any kind of fancy attack at all? In other words it seems like there should be a very difficult step between "running arbitrary code" and "gaining root permissions" but you never hear about that.

One idea that just occured to me is that maybe if the program you're attacking is running as root then your code will have root priviliges as well, but users can't execute any code as root. Is this correct or is was my original question valid? --frothT C 19:56, 29 September 2006 (UTC)[reply]

Ding ding ding! Convincing the system to run arbitrary code as root is a very fast way to complete control, whereas normal user level security protects against this attack. System binaries that will be executed as root are protected from editing by users, and any programs a user creates to run on the system will only have that user's level of permission. For an anonymous attacker to be able to introduce a binary (or part of a binary) for execution as root is a huge problem indeed. See Buffer overflow and Arbitrary code for more info. --Jmeden2000 20:39, 29 September 2006 (UTC)[reply]
The reason running arbitrary code is automatically associated with gaining root-level permissions is because of privilege escalation attacks. Because of the wider attack surface, there are usually more priviledge escalation attacks than remote arbitrary code execution attacks, and also the remote attacks tend to get more attention, for obvious reasons. --cesarb 19:56, 30 September 2006 (UTC)[reply]

There is, indeed, a Unix COMMAND that gives the user root permissions; sudo is its name. It can be called from a shell script as well. After authentication via an admin password, for a default of 5 minutes, the user may use sudo again to run commands as root. For instance:

sudo nano /var/etc/thefileiwanttoedit.txt

would edit the file mentioned as root, thus giving total control over that file. Furthermore, in regards to installation of programs, programs installed via sudo make (insert parameters here) would give thre program root permissions.

Hope this helped ;-) Bellito 19:57, 22 October 2006 (UTC)[reply]

Tables by column? edit

Has there been any move to make HTML or MediaWiki tables where the cells are grouped by column, or not at all, rather than by row? This could (a) make it easier to shift cells down, when editing a table manually; and (b) tell screen readers to read the table sideways. It seems to me this could be done in two ways in HTML, if the standard were changed appropriately:

<table>
 <tcol> <!-- The current tcol is for formatting only, and doesn't allow any children -->
  <th> Column 1 Row 1 </th>
  <td> Column 1 Row 2 </td>
  <td> Column 1 Row 3 </td>
 </tcol>
 <tcol>
  <th> Column 2 Row 1 </th>
  <td> Column 2 Row 2 </td>
  <td> Column 2 Row 3 </td>
 </tcol>
</table>
<table rows=3 cols=2>
 <th row=1 col=1> Column 1 Row 1 </th>
 <td row=2 col=1> Column 1 Row 2 </td>
 <td row=3 col=1> Column 1 Row 3 </td>
 <th row=1 col=2> Column 2 Row 1 </th>
 <td row=2 col=2> Column 2 Row 2 </td>
 <td row=3 col=2> Column 2 Row 3 </td>
</table>

NeonMerlin 22:30, 29 September 2006 (UTC)[reply]

I do not have inside information about the deliberations of standards groups, but my impression is that there would be a great deal of resistance among implementors. With such a table structure it would be necessary to read the complete table before setting the first row of it. The current table design tries to make that avoidable. To quote from the HTML 4.01 standard:

The HTML table model has been designed so that, with author assistance, user agents may render tables incrementally (i.e., as table rows arrive) rather than having to wait for all the data before beginning to render.
In order for a user agent to format a table in one pass, authors must tell the user agent:
  • The number of columns in the table. Please consult the section on calculating the number of columns in a table for details on how to supply this information.
  • The widths of these columns. Please consult the section on calculating the width of columns for details on how to supply this information.
More precisely, a user agent may render a table in a single pass when the column widths are specified using a combination of COLGROUP and COL elements. If any of the columns are specified in relative or percentage terms (see the section on calculating the width of columns), authors must also specify the width of the table itself.

Still, it is not out of the question. Even the current model can be forced to read the complete table to calculate column widths. (The difference is, the proposed model must always read the complete table.) Meanwhile, use a WYSIWYG editor to make the desired manipulation convenient. --KSmrqT 05:19, 30 September 2006 (UTC)[reply]
Actually, tables could still be rendered piecemeal in the column-by-column model, only they'd proceed sideways.
Also, what WYSIWYG editor would you recommend? I've tried WordPerfect, Microsoft Word, OpenOffice.org Writer and FrontPage, and they all produce garbled, inelegant output that requires further manual editing. (Often, they will also throw away some of the existing formatting.) For instance, if I open the following file with OOo Writer,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<title>DMCI Game Development Club</title>
<link rel="stylesheet" href="default.css">
</head>

<body>
<table cellspacing="0px" cellpadding="0px" align="center" class="header">
<tr>
<td colspan=5><h1>DMCI Game Development Club</h1></td>
</tr>

<tr>
<td class="tab"><img src="interface_images/tab.gif" class="tab" /><div class="tab">Active Tab</div></td>
<td class="tab"><img src="interface_images/inactivetab.gif" class="tab" /><div class="tab">Other Tab 1</div></td>
<td class="tab"><img src="interface_images/inactivetab.gif" class="tab" /><div class="tab">Other Tab 2</div></td>
<td class="tab"><img src="interface_images/inactivetab.gif" class="tab" /><div class="tab">Other Tab 3</div></td>
<td class="tab"><img src="interface_images/inactivetab.gif" class="tab" /><div class="tab">Other Tab 4</div></td>
</tr>
</table><table cellspacing="0px" cellpadding="0px" align="center" class="main"><tr>

<td class="hborder"><img src="interface_images/borderleft.gif" class="hborder"></td>
<td class="textpanel">

<h2>Welcome!</h2>
<p>This is your main panel. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

</td>
<td class="hborder"><img src="interface_images/borderright.gif" class="hborder"></td></tr>

<tr><td class="cborder"><img src="interface_images/borderbottomleft.gif" class="cborder"></td>
<td class="vborder"><img src="interface_images/borderbottom.gif" class="vborder"></td>
<td class="cborder"><img src="interface_images/borderbottomright.gif" class="cborder"></td></tr>
</table>
</body>
</html>
and save it, without typing or clicking in any changes, it turns into the following:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
 <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
 <TITLE>DMCI Game Development Club</TITLE>
 <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.0  (Win32)">
 <META NAME="CREATED" CONTENT="20060930;12015804">
 <META NAME="CHANGED" CONTENT="16010101;0">
 <STYLE>
 <!--
 TD P { margin-bottom: 0cm }
 H1 { text-align: center }
 -->
 </STYLE>

</HEAD>
<BODY LANG="en-GB" BACKGROUND="interface_images/background.gif" DIR="LTR">
<CENTER>
 <TABLE CELLPADDING=0 CELLSPACING=0 STYLE="page-break-before: always">
 <TR>
 <TD COLSPAN=5>
 <H1>DMCI Game Development Club</H1>
 </TD>
 </TR>
 <TR>

 <TD>
 <P><IMG SRC="interface_images/tab.gif" NAME="graphics1" ALIGN=BOTTOM WIDTH=120 HEIGHT=30 BORDER=0></P>
 <P>Active Tab</P>
 </TD>
 <TD>
 <P><IMG SRC="interface_images/inactivetab.gif" NAME="graphics2" ALIGN=BOTTOM WIDTH=120 HEIGHT=30 BORDER=0></P>
 <P>Other Tab 1</P>
 </TD>

 <TD>
 <P><IMG SRC="interface_images/inactivetab.gif" NAME="graphics3" ALIGN=BOTTOM WIDTH=120 HEIGHT=30 BORDER=0></P>
 <P>Other Tab 2</P>
 </TD>
 <TD>
 <P><IMG SRC="interface_images/inactivetab.gif" NAME="graphics4" ALIGN=BOTTOM WIDTH=120 HEIGHT=30 BORDER=0></P>
 <P>Other Tab 3</P>
 </TD>

 <TD>
 <P><IMG SRC="interface_images/inactivetab.gif" NAME="graphics5" ALIGN=BOTTOM WIDTH=120 HEIGHT=30 BORDER=0></P>
 <P>Other Tab 4</P>
 </TD>
 </TR>
 </TABLE>
</CENTER>
<CENTER>
 <TABLE CELLPADDING=0 CELLSPACING=0>

 <TR>
 <TD BGCOLOR="#eeddcc">
 <P><IMG SRC="interface_images/borderleft.gif" NAME="graphics6" ALIGN=BOTTOM WIDTH=15 HEIGHT=1 BORDER=0></P>
 </TD>
 <TD BGCOLOR="#eeddcc">
 <H2>Welcome!</H2>
 <P STYLE="margin-bottom: 0.5cm">This is your main panel. Lorem
 ipsum dolor sit amet, consectetur adipisicing elit, sed do
 eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
 enim ad minim veniam, quis nostrud exercitation ullamco laboris
 nisi ut aliquip ex ea commodo consequat.</P>
 <P>Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
 cupidatat non proident, sunt in culpa qui officia deserunt mollit
 anim id est laborum.</P>

 </TD>
 <TD BGCOLOR="#eeddcc">
 <P><IMG SRC="interface_images/borderright.gif" NAME="graphics7" ALIGN=BOTTOM WIDTH=15 HEIGHT=1 BORDER=0></P>
 </TD>
 </TR>
 <TR>
 <TD BGCOLOR="#eeddcc">
 <P><IMG SRC="interface_images/borderbottomleft.gif" NAME="graphics8" ALIGN=BOTTOM WIDTH=15 HEIGHT=15 BORDER=0></P>
 </TD>

 <TD BGCOLOR="#eeddcc">
 <P><IMG SRC="interface_images/borderbottom.gif" NAME="graphics9" ALIGN=BOTTOM WIDTH=1 HEIGHT=15 BORDER=0></P>
 </TD>
 <TD BGCOLOR="#eeddcc">
 <P><IMG SRC="interface_images/borderbottomright.gif" NAME="graphics10" ALIGN=BOTTOM WIDTH=15 HEIGHT=15 BORDER=0></P>
 </TD>
 </TR>
 </TABLE>
</CENTER>

<P><BR><BR>
</P>
</BODY>
</HTML>
These render very differently, in both IE and Firefox. The former is CSS-compliant; the latter isn't, and causes quirks mode. (I can provide the external CSS I was using, too, if it makes a difference.) NeonMerlin 15:57, 30 September 2006 (UTC)[reply]
Did you try Nvu or Quanta? --cesarb 19:45, 30 September 2006 (UTC)[reply]
The questioner appears to assume that you have to enter tables as:
<table>
 <tr>
  <td>top left</td>
  <td>top right</td>
 </tr>
 <tr>
  <td>bottom left</td>
  <td>bottom right</td>
 </tr>
</table>
That is not the case. You do not need all the newlines. You are perfectly allowed to use:
<table>
<tr> <td>top left</td>    <td>top right</td>    </tr>
<tr> <td>bottom left</td> <td>bottom right</td> </tr>
</table>
Now, it looks nearly the same as it does on the page. --Kainaw (talk) 22:52, 30 September 2006 (UTC)[reply]

Basic, low-level audio on Windows edit

I'm interested in coding a program (in C\C++ or Python) for some low-level audio control in Windows. What I mean is, I want to deal with the actual samples from the stereo output. I don't want to import sound files or anything like that, I just want to output audio based on direct manipulation of samples, which is what this program should do. Example, I want to be able to play a 440 Hz sine wave sound by just writing samples following the sine function over time (using the sample rate and the frequency to get the said 440 Hz)

Any suggestions on where to start? I'm not very experienced in either C\C++ or Python, but I just need a few complex and interesting projects to push my skills further. Thanks! - L.

All you need to do is to configure the audio device and push sample buffers at it - to synthesise waveforms, you quite literally just make up a sine wave (using, generally, the sin() function) that repeats at the rate you want (and hence the frequency of the sound) and with the amplitude multiplied up so that the sound is audible. On windows in C you'd probably use DirectSound, in Python you'd probably use Pygame. I'm afraid I don't have an example program in either, but below is a simple sin synthesiser which uses the unix /dev/dsp sound interface (which, incidentally, works fine in cygwin). Apart from the audio-device stuff there's just some very basic stuff that builds a waveform from the sine function before playing it. The code is a little more complicated than you absolutely basically need, as it has a simple envelope which fades the volume in and out for each note (without this you hear a nasty click at the beginning and end).

/* 
  playwave.c 

  Copyright (c) 2005 W. Finlay McWalter
  Licence: your choice of GPL, GFDL, or CCbySA

  Plays a given tone for a brief period of time, using the system's /dev/dsp
  interface.  Tested using cygwin (should work on linux too).

  Version history:
  v1.   Basic version
  v2.   Adds simple envelope (attack and release) to avoid nasty clicks
        between notes
  v3.   Change to 16 bit signed (LE) output (wow, so much better), and
        make envelope code more programmable.


  Notes:
  - Current build produces signed 16 bit 44100 Hz mono little endian raw PCM
  - Samples are appended to a file called "./outfile".  This allows importing
    the data into audacity and listening to it without the gaps imposed
    by multiple invocations of the program.

  Help on tone arithmetic: http://en.wikipedia.org/wiki/Physics_of_music

  Programming notes:
    http://www.oreilly.de/catalog/multilinux/excerpt/ch14-05.htm
    http://davmac.org/davpage/linux/linux-sound.html
    http://www.4front-tech.com/pguide/audio.html

  Sample invocation (close encounters):
    rm outfile ; touch outfile ; ./playwave 440 10000 ; ./playwave 495 10000 ; 
    ./playwave 392 10000 ; ./playwave 196 10000 ; ./playwave 294 10000
  
*/

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/soundcard.h>
#include <math.h>

#define CHANNELS 1 
#define RATE     44100     /* samples/sec */
#define LENGTH   0.8f      /* seconds */
#define SIZE     2        /* bytes per sample */
#define NUM_SAMPLES_PER_BUFFER ((int)(LENGTH*RATE*SIZE*CHANNELS)/2)

// ENVELOPE FRACTION defines the proportion of the sample buffer that
// is shaped by the envelope function.  So to shape the beginning and
// ending 10th, set envelope fraction to 10.  ENVELOPE_FRACTION must
// be an integer.
#define ENVELOPE_FRACTION 3

int main (int argc, char** argv){
  int             audioDevice; 
  int             outfile;
  int             status;
  unsigned int    arg;
  int             counter;
  int             x;
  float           angle;
  int             num_samples_in_waveform;
  float           volume = 6.0f;
  signed short    buf[NUM_SAMPLES_PER_BUFFER];
  int             freq = 440;
  float           value;
  float           vol_multiplier;

  if (argc != 3){
    fprintf(stderr, "usage: playwave <frequency> <volume>");
    exit(1);
  }
  freq = atof(argv[1]);
  volume = atof(argv[2]);

  /* compute waveform */
  num_samples_in_waveform = RATE/freq;

  for (x=0; x< NUM_SAMPLES_PER_BUFFER; x++){
    angle = (2.0f * 3.14159f * (float)x) / (float)num_samples_in_waveform;
    value = sin(angle);

    vol_multiplier = 1.0f;

    // envelope: lead in
    if(x < (NUM_SAMPLES_PER_BUFFER/ENVELOPE_FRACTION)){
      vol_multiplier =  (ENVELOPE_FRACTION * (float)x) / ((float)NUM_SAMPLES_PER_BUFFER) ;
    }

    // envelope: lead out 
    if(x > ((ENVELOPE_FRACTION-1)*NUM_SAMPLES_PER_BUFFER)/ENVELOPE_FRACTION){
      vol_multiplier =  (ENVELOPE_FRACTION * (NUM_SAMPLES_PER_BUFFER-x)) / ((float)NUM_SAMPLES_PER_BUFFER) ;
    }

    buf[x] = (signed short)(volume * value * vol_multiplier);
  }

  outfile = open("outfile", O_RDWR|O_APPEND|O_CREAT);
  if (outfile < 0) {
    perror("open of opening outfile failed");
    exit(1);
  }
  status = write(outfile, buf, sizeof(buf));
  if (status != sizeof(buf))
    perror("wrote wrong number of bytes");

  close(outfile);


  // Now write that out to the audio device

  /* open sound device */
  audioDevice = open("/dev/dsp", O_RDWR);
  if (audioDevice < 0) {
    perror("open of /dev/dsp failed");
    exit(1);
  }

  /* set format */
  arg = AFMT_S16_LE;
  status = ioctl(audioDevice, SNDCTL_DSP_SETFMT, &arg);
  if (status == -1) {
    perror("SNDCTL_DSP_SETFMT");
    exit(1);
  }

  arg = CHANNELS;  /* mono or stereo */
  status = ioctl(audioDevice, SOUND_PCM_WRITE_CHANNELS, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
  if (arg != CHANNELS)
    perror("unable to set number of channels");

  arg = RATE;    /* sampling rate */
  status = ioctl(audioDevice, SOUND_PCM_WRITE_RATE, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_WRITE ioctl failed");

  status = write(audioDevice, buf, sizeof(buf));
  if (status != sizeof(buf))
    perror("wrote wrong number of bytes");

  /* wait for playback to complete before recording again */
  status = ioctl(audioDevice, SOUND_PCM_SYNC, 0); 
  if (status == -1)
    perror("SOUND_PCM_SYNC ioctl failed");

  close(audioDevice);
}


Here is something I cooked up a couple of years ago. It's shit, but it might give you some ideas. It creates a raw integer soundfile with no specific formatting or header information... Magic Window 15:34, 1 October 2006 (UTC)[reply]


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void SineGen(float step, int length, FILE *fp);
void NoiseGen(int length, FILE *fp);
void SquareGen(float step, int length, FILE *fp);
 
#define PI      3.14159265
#define S_RATE  44100          // Sample rate
#define B_RATE  32768          // Bit rate (16 bits = 2^16 / 2 = 32768)
 
int main()
{
    short unsigned int choice;
    unsigned int length; 
    float freq, step;   

    do
    {
        printf("\nEnter frequency: ");
        scanf("%f", &freq);

        if (freq < 1) 
        { 
            printf("Incorrect frequency.");
            continue;
        }

        printf("\nEnter length: ");
        scanf("%i", &length);

        if (length < 1)
        {  
            printf("Incorrect length.");
            continue;
        }

        printf("\n1. Sine wave\n2. White noise\n3. Square wave\n\nChoice? ");
        scanf("%i", &choice);

        if (choice < 1 || choice > 3)
        {  
            printf("Bad choice.");
            continue;
        }
    }
    while(freq < 1 && length < 1 && choice < 1 || choice > 3);
    
    step = (freq / S_RATE);                              // Converts frequency (Hz) into step size.

    FILE *fp;
    fp = fopen("wave.raw", "w");                         // Open the file, and write.

    switch (choice)
    {
        case 1: SineGen(step, length, fp); break;
        case 2: NoiseGen(length, fp); break;
        case 3: SquareGen(step, length, fp);                     
        default: break;
    }
    
    fclose(fp);                                          // File written, close.

    getch();                                            
    return 0;
}

void SineGen(float step, int length, FILE *fp)
{   
    int j;
    float sample, i;

    step *= 360;

    for (j = 0; j < length; ++j)
        for (i = 0; i < 360; i += step)                  // The pitch is raised by increasing the step size. 
        {
            sample = (sin(i * PI / 180)) * B_RATE;       // Convert degrees to radians for sin(), scale float to correct amplitude.         
            fprintf(fp, "%i\t", (int) sample);           // Cast to int for correct parsing by wave editor.                  
            printf("%i\t", (int) sample);                // Display as integers.
        }
}

void NoiseGen(int length, FILE *fp)
{

    srand((unsigned)time(NULL));                         // Uses system clock as inital seed.  

    int j, randsamp;

    for (j = 0; j < length; ++j)
    {   
        randsamp = ((B_RATE * 2) * rand() / RAND_MAX) - B_RATE;    // Generates random number between -B_RATE to B_RATE.
        fprintf(fp, "%i\t", randsamp);
        printf("%i\t", randsamp);
    } 
}

void SquareGen(float step, int length, FILE *fp)
{
    int j;
    float i;

    step = 1 / step;

    for (j = 0; j < length; ++j)
    {
        for (i = 0; i < step; ++i)
        {
            fprintf(fp, "%i\t", -B_RATE); 
            printf("%i\t", -B_RATE);
        }

        for (i = 0; i < step; ++i)
        {
            fprintf(fp, "%i\t", B_RATE); 
            printf("%i\t", B_RATE);
        }
    }
}