.

Saturday, August 30, 2008

Audio in C# .NET

Audio in C# .NET

Within the .NET development environment the availability of playing audio is limited. For one, the SoundPlayer that ships with the .NET framework will currently work with wav files (understandable because of license agreements). Once more with WMA you have to use the Windows Media Player control that ships as a Com object. Nevertheless, there are altenatives. As stated on there website:

BASS is an audio library for use in Windows and Mac OSX software. Its purpose is to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a tiny DLL, under 100KB* in size.

On Windows, BASS requires DirectX 3 or above for output, and takes advantage of DirectSound and DirectSound3D hardware accelerated drivers, when available. On OSX, BASS uses CoreAudio for output, and OSX 10.3 or above is recommended. Both PowerPC and Intel Macs are supported.

If you have everything downloaded and installed in order then you are ready to begin. Start by creating a new windows project.I've named my project BassAudio. Right-click on your project and add the following reference.

Following this addition you will need to add the actual C++ library to your executing folder. I've added mine to my project and changed the output property to always copy.

This dll should be wherever you downloaded it to on your machine. If you forgot to download it see the third download link I mentioned above.

Next, you will want to add whatever song you like. I'm using an Mp3 song that I have on my machine. Just make sure the file will copy to the output directory.

Now that everything has been setup. We can start coding to the api.

Within the Bass api there are a number of varying things you can do with audio devices. For instance, you can work with 3D audio including velocity, position of the emitting sound, position of the listener, doppler effects... and much more.

I recommend taking a look at all that's available to you in the Un4seen.Bass.Bass functions. The nice part is that the majority of all the methods in this api are within the Bass class.

Whenever you're ready, initialize the default device with -1 for the first parameter.

The second parameter is the sampling rate. I recommend looking up the definition on either Wikipedia or HowStuffWorks since I'd rather not explain this part. Basically your audio device has a rate at which it can sample whatever particular input you're working with. Speakers will sample your song at such a rate, or your microphone will sample the audio coming in at such a rate. 44100 is just about the best quality for sampling you can get.

Creating the stream is pretty easy. All you have to do is call the function:

The parameters to this function are pretty much self-explanatory when you read the comments. The first is the location of the file, the second parameter is the offset to begin the streaming from, the length is how long to stream (0 is all), the last parameter is the BassStream flags. I recommend taking a look at the comments in the enumerations. They are all very helpful.

Note: When you work with unmanaged code, you have to be sure you save your references; otherwise, the .NET garbage collector will destroy the reference. To do this, I've simply placed the int stream at the top of the class.

Add a PlaySong, StopSong, and a destructor to your Player class.


The destructor in this class makes sure that all the resources are let go from the unmanaged part of the bass api. Okay, now that we have a simple player setup, let's actually use it! :D

By the end of your form you might have something like this:

Awesome, create the player on load, create a few event-handlers to the buttons and call the player's functions.

And there you have it. Hit F5, load your song and click play. You should now be hearing you song.

In this tutorial you learned how to use an alternative sound api to stream sound to a audio device of your choosing. You figured out what sampling meant and you created a nice reusable sound player. In the my next audio tutorial, I'll show you how to use BASS to show a list of all your audio devices. Then we'll get into some microphone recording later on. Leave and questions and comments here if you like.

Wednesday, August 20, 2008

Functions used in sql server

Single-Row Functions

Single-row functions return a single result row for every row of a queried table or view. These functions can appear in select lists, WHERE clauses, START WITH and CONNECT BY clauses, and HAVING clauses.

Numeric Functions

Numeric functions accept numeric input and return numeric values. Most numeric functions that return NUMBER values that are accurate to 38 decimal digits. The transcendental functions COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN, and TANH are accurate to 36 decimal digits. The transcendental functions ACOS, ASIN, ATAN, and ATAN2 are accurate to 30 decimal digits. The numeric functions are:


ABS
ACOS
ASIN
ATAN
ATAN2
BITAND
CEIL
COS
COSH
EXP
FLOOR
LN
LOG
MOD
NANVL
POWER
REMAINDER
ROUND (number)
SIGN
SIN
SINH
SQRT
TAN
TANH
TRUNC (number)
WIDTH_BUCKET

Character Functions Returning Character Values

Character functions that return character values return values of the same datatype as the input argument. The length of the value returned by the function is limited by the maximum length of the datatype returned.

  • For functions that return CHAR or VARCHAR2, if the length of the return value exceeds the limit, then Oracle Database truncates it and returns the result without an error message.

  • For functions that return CLOB values, if the length of the return values exceeds the limit, then Oracle raises an error and returns no data.

The character functions that return character values are:


CHR
CONCAT
INITCAP
LOWER
LPAD
LTRIM
NLS_INITCAP
NLS_LOWER
NLSSORT
NLS_UPPER
REGEXP_REPLACE
REGEXP_SUBSTR
REPLACE
RPAD
RTRIM
SOUNDEX
SUBSTR
TRANSLATE
TREAT
TRIM
UPPER

Character Functions Returning Number Values

Character functions that return number values can take as their argument any character datatype.

The character functions that return number values are:


ASCII
INSTR
LENGTH
REGEXP_INSTR

Datetime Functions

Datetime functions operate on date (DATE), timestamp (TIMESTAMP, TIMESTAMP WITH TIME ZONE, and TIMESTAMP WITH LOCAL TIME ZONE), and interval (INTERVAL DAY TO SECOND, INTERVAL YEAR TO MONTH) values.

Some of the datetime functions were designed for the Oracle DATE datatype (ADD_MONTHS, CURRENT_DATE, LAST_DAY, NEW_TIME, and NEXT_DAY). If you provide a timestamp value as their argument, Oracle Database internally converts the input type to a DATE value and returns a DATE value. The exceptions are the MONTHS_BETWEEN function, which returns a number, and the ROUND and TRUNC functions, which do not accept timestamp or interval values at all.

The remaining datetime functions were designed to accept any of the three types of data (date, timestamp, and interval) and to return a value of one of these types.

The datetime functions are:


ADD_MONTHS
CURRENT_DATE
CURRENT_TIMESTAMP
DBTIMEZONE
EXTRACT (datetime)
FROM_TZ
LAST_DAY
LOCALTIMESTAMP
MONTHS_BETWEEN
NEW_TIME
NEXT_DAY
NUMTODSINTERVAL
NUMTOYMINTERVAL
ROUND (date)
SESSIONTIMEZONE
SYS_EXTRACT_UTC
SYSDATE
SYSTIMESTAMP
TO_CHAR (datetime)
TO_TIMESTAMP
TO_TIMESTAMP_TZ
TO_DSINTERVAL
TO_YMINTERVAL
TRUNC (date)
TZ_OFFSET

Collection Functions

The collection functions operate on nested tables and varrays. The SQL collection functions are:


CARDINALITY
COLLECT
POWERMULTISET
POWERMULTISET_BY_CARDINALITY
SET

Aggregate Functions

Aggregate functions return a single result row based on groups of rows, rather than on single rows. Aggregate functions can appear in select lists and in ORDER BY and HAVING clauses. They are commonly used with the GROUP BY clause in a SELECT statement, where Oracle Database divides the rows of a queried table or view into groups. In a query containing a GROUP BY clause, the elements of the select list can be aggregate functions, GROUP BY expressions, constants, or expressions involving one of these. Oracle applies the aggregate functions to each group of rows and returns a single result row for each group.

If you omit the GROUP BY clause, then Oracle applies aggregate functions in the select list to all the rows in the queried table or view. You use aggregate functions in the HAVING clause to eliminate groups from the output based on the results of the aggregate functions, rather than on the values of the individual rows of the queried table or view.


See Also:

"Using the GROUP BY Clause: Examples" and the "HAVING Clause " for more information on the GROUP BY clause and HAVING clauses in queries and subqueries

Many (but not all) aggregate functions that take a single argument accept these clauses:

  • DISTINCT causes an aggregate function to consider only distinct values of the argument expression.

  • ALL causes an aggregate function to consider all values, including all duplicates.

For example, the DISTINCT average of 1, 1, 1, and 3 is 2. The ALL average is 1.5. If you specify neither, then the default is ALL.

All aggregate functions except COUNT(*) and GROUPING ignore nulls. You can use the NVL function in the argument to an aggregate function to substitute a value for a null. COUNT never returns null, but returns either a number or zero. For all the remaining aggregate functions, if the data set contains no rows, or contains only rows with nulls as arguments to the aggregate function, then the function returns null.

You can nest aggregate functions. For example, the following example calculates the average of the maximum salaries of all the departments in the sample schema hr:

SELECT AVG(MAX(salary)) FROM employees GROUP BY department_id;

AVG(MAX(SALARY))
----------------
10925

This calculation evaluates the inner aggregate (MAX(salary)) for each group defined by the GROUP BY clause (department_id), and aggregates the results again.

The aggregate functions are:


AVG
COLLECT
CORR
CORR_*
COUNT
COVAR_POP
COVAR_SAMP
CUME_DIST
DENSE_RANK
FIRST
GROUP_ID
GROUPING
GROUPING_ID
LAST
MAX
MEDIAN
MIN
PERCENTILE_CONT
PERCENTILE_DISC
PERCENT_RANK
RANK
REGR_ (Linear Regression) Functions
STATS_BINOMIAL_TEST
STATS_CROSSTAB
STATS_F_TEST
STATS_KS_TEST
STATS_MODE
STATS_MW_TEST
STATS_ONE_WAY_ANOVA
STATS_T_TEST_*
STATS_WSR_TEST
STDDEV
STDDEV_POP
STDDEV_SAMP
SUM
VAR_POP
VAR_SAMP
VARIANCE

Saturday, August 9, 2008

Hit Enter Key in ASP.NET page

Hit Enter Key in ASP.NET page

Scenario:
It's very common for the user to hit the Enter key after they have entered the required data in the text box.

For example, when you want to Login.
After keying in your user name and password, instead of clicking on the "Login" button, you may also hit the Enter key to login.

Solution 1:
In order to do this, ASP.NET 2.0 has provided a property in Form and Panel controls, which is "DefaultButton".
You can set the DefaultButton property to the button name, so that whenever user hits the Enter key in the form or panel, the button clicked event will be triggered.

Solution 2:
Well, I was having an issue with the DefaultButton.
I'm not using panel to group my controls, as panel is having some problem with IE7.
I've found a solution with using javascript, it's simple and nice to use. (You do not need to edit your current UI for this.)

Create this function:

public static void AddEnterKeyAttribute(TextBox txt, ImageButton iBtn)
{

txt.Attributes.Add("onkeydown",
"if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById('" +
iBtn.UniqueID + "').click();return false;}} else {return true}; ");
}


The keycode for enter key is 13.
When a key is pressed in textbox it will check the keycode is 13. If it is 13 the relevant button will be clicked.
event.keycode will not work with firefox, so we are using event.which.

You can create multiple similar functions for different web controls.
Perhaps you can also create a general function which accept any kind of web controls. I haven't try this yet.

You just need to add this in Page_Load event, for all the web controls that you want to trigger the button clicked event when user hits the Enter key:

AddEnterKeyAttribute(txtPassword, ibtnLogin);

Auto Set Focus to Next control

Auto Set Focus to Next control
Scenario:
You may want to auto set the focus to the next textbox, when the user has typed the exact length in the current textbox.
For example:
Telephone number: (012)-(12345678)
The max length for the first textbox is 3, after user typed in "012" which already reached the max length, the the focus should automatically set to the next text box.

Thanks for my colleague, Carmen, who helped me to find the following solution.

Add the following script to the block:

Copy this function in the code file:
public static void AddNextTabAttribute(TextBox txt1,
TextBox txt2)
{
//Set next tab attribute when key up
txt1.Attributes.Add("OnKeyUp", "Tab(this, '" +
txt2.ClientID + "')");
}

Whenever the "KeyUp" event has trigged in the first textbox, it'll call the Tab() function and check if it has reached its max length.

Then, call this function in Page_Load event to add the attributes to the textbox.
AddNextTabAttribute(txtPhoneNo1, txtPhoneNo2);

That's it!
I am not sure if there is a better way to do this, I find that it's very powerful to combine Javascript in ASP.NET.

Auto Fillup Leading Zero in Textbox

Auto Fill up Leading Zero(s)

Scenario:
There came another requirement.
When the user didn't key in the max length in the first text box, leading zero(s) will automatically be added to fill up the space.
For example:
Telephone number: (12)-(12345678)
If the user only entered "12", it hasn't reached the max length (3) yet, then a leading zero will be added to become "012".

I'm still using the javascript here. Add the following script in the block:

<script language=javascript>

function AddLeadingZero(currentField)
{
//Check if the value length hasn't reach its max length yet
if (currentField.value.length != currentField.maxLength)
{
//Add leading zero(s) in front of the value
var numToAdd = currentField.maxLength - currentField.value.length;
var value ="";
for (var i = 0; i
< numToAdd;i++)
{
value += "0";
}

currentField.value = value + currentField.value;
}
}


script>

Copy this function in the code file:

public static void AddLeadingZeroAttribute(TextBox txt)
{
//Add leading zero when focus is lost
txt.Attributes.Add("OnBlur", "AddLeadingZero(this)");

}


"OnBlur" event will be triggered when the textbox loses the focus.
Whenever the user finished keying in values and left the textbox, the AddLeadingZero() function will be called.

Set security access to folder

Set security access to folder

I'm currently doing a small function, where I need to create folder dynamically, if the folder does not exist.

Creating folder is easy, but I also need to set the security access. Finally, I've found the way of doing this. Happy

I have created a simple class to perform this Directory-related tasks, named "Folder".

Firstly, we need to include System.IO (for Directory class) & System.Security.AccessControl (for FileSystemRights & AccessControlType enums).

public static bool Exists(string folderPath)
{
return Directory.Exists(folderPath);
}

public static void Create(string folderPath)
{
Directory.CreateDirectory(folderPath);
}

public static void Delete(string folderPath)
{
Directory.Delete(folderPath, true);
}

public static void AddSecurity(string folderPath,
string userAccount,
FileSystemRights fileSystemRights,
AccessControlType controlType)
{
DirectoryInfo folderInfo = new DirectoryInfo(folderPath);

DirectorySecurity folderSecurity = folderInfo.GetAccessControl();

folderSecurity.AddAccessRule(
new FileSystemAccessRule(userAccount, fileSystemRights, controlType));

folderInfo.SetAccessControl(folderSecurity);

}

public static void RemoveSecurity(string folderPath,
string userAccount,
FileSystemRights fileSystemRights,
AccessControlType controlType)
{
DirectoryInfo folderInfo = new DirectoryInfo(folderPath);

DirectorySecurity folderSecurity = folderInfo.GetAccessControl();

folderSecurity.RemoveAccessRule(
new FileSystemAccessRule(userAccount, fileSystemRights, controlType));

folderInfo.SetAccessControl(folderSecurity);

}

public static string[] GetListOfFileSystemRights()
{
return Enum.GetNames(typeof(FileSystemRights));
}

public static string[] GetListOfAccessControlTypes()
{
return Enum.GetNames(typeof(AccessControlType));
}




Function: If the folder does not exist, create it and set security access.



if (Folder.Exists(folderPath) == false)
{
Folder.Create(folderPath);
Folder.AddSecurity(folderPath,"MY\\CHONGLK", FileSystemRights.Modify,AccessControlType.Allow);
}







To remove the security access for certain rights, use the RemoveSecurity method:



Folder.RemoveSecurity(folderPath,"MY\\CHONGLK", FileSystemRights.Modify,AccessControlType.Allow);




The last two functions is to allow users to bind the list of enum values to the UI control.



//List all FileSystemRights values in dropdownlist
systemRightsDropDownList.DataSource = Folder.GetListOfFileSystemRights();
systemRightsDropDownList.DataBind();

//List all AccessControlTypes values in dropdownlist
controlTypeDropDownList.DataSource = Folder.GetListOfAccessControlTypes();
controlTypeDropDownList.DataBind();




It's quite simple, but I didn't know these methods before this. Tongue At least, I learnt something new.

Friday, August 8, 2008

Rounded corners using CSS

Rounded corners using CSS

Ever wonder how to make the rounded corners in your web site?

I've read about using images to make it, and some need javascripts. You can use ASP.NET AJAX tool for this rounded corners box. I just found this, where you don't need to use any images nor javascript, and it works.

Copy this to your css file. e.g. test.css

   1: /* ROUNDED CORNERS - Grey border */
   2: #xsnazzy h1, #xsnazzy h2, #xsnazzy p {margin:0 10px; letter-spacing:1px;}
   3: #xsnazzy h1 {font-size:2.5em; color:#fff;}
   4: #xsnazzy h2 {font-size:2em;color:#06a; border:0;}
   5: #xsnazzy p {padding-bottom:0.5em;}
   6: #xsnazzy h2 {padding-top:0.5em;}
   7: #xsnazzy {background: transparent; margin:1em;}
   8:  
   9: .xtop, .xbottom {display:block; background:transparent; font-size:1px;}
  10: .xb1, .xb2, .xb3, .xb4 {display:block; overflow:hidden;}
  11: .xb1, .xb2, .xb3 {height:1px;}
  12: .xb2, .xb3, .xb4 {border-left:1px solid #ccc; border-right:1px solid #ccc;}
  13: .xb1 {margin:0 5px; background:#ccc;}
  14: .xb2 {margin:0 3px; border-width:0 2px;}
  15: .xb3 {margin:0 2px;}
  16: .xb4 {height:2px; margin:0 1px;}
  17:  
  18: .xboxcontent 
  19: {
  20:     display:block; 
  21:     border:0 solid #ccc; 
  22:     border-width:0 1px;
  23: }

Copy this to the HTML file:



   1: <div id="xsnazzy">
   2: <b class="xtop">
   3: <b class="xb1">b><b class="xb2">b><b class="xb3">b><b class="xb4">b>
   4: b>
   5: <div class="xboxcontent">
   6: <p><h2>This is an example of rounded corner box without using images or javascript.h2>p>
   7: div>
   8: <b class="xbottom">
   9: <b class="xb4">b><b class="xb3">b><b class="xb2">b><b class="xb1">b>
  10: b>
  11: div>

In order to use the css file, you need to include this line of code in the head block.



   1: <head>
   2: <link href="Test.css" rel="stylesheet" type="text/css" />
   3:     <title>Rounded Corners exampletitle>
   4: head>


Then, you'll get the rounded corners box.


More information regarding the rounded corners:

* Snazzy Borders - This is where I got the codes for my example.

* Spiffy Corners - Another way to create anti-aliased corners without using images or javascript.

* CSS Rounded Corners 'Roundup' - A collection of techniques to create boxes with rounded corners using CSS. Here you'll find many different techniques.

* Nifty Corners - This technique creates rounded corners without images, but with javascript.

.